diff options
Diffstat (limited to 'indra/newview')
242 files changed, 21495 insertions, 13984 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 24c16d22bf..1e5a798202 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -95,6 +95,7 @@ set(viewer_SOURCE_FILES llchannelmanager.cpp llchatbar.cpp llchatitemscontainerctrl.cpp + llchathistory.cpp llchatmsgbox.cpp llchiclet.cpp llclassifiedinfo.cpp @@ -159,7 +160,6 @@ set(viewer_SOURCE_FILES llfloatercolorpicker.cpp llfloatercustomize.cpp llfloaterdaycycle.cpp - llfloaterdirectory.cpp llfloaterenvsettings.cpp llfloaterfriends.cpp llfloaterfonttest.cpp @@ -195,6 +195,7 @@ set(viewer_SOURCE_FILES llfloaterregioninfo.cpp llfloaterreporter.cpp llfloaterscriptdebug.cpp + llfloatersearch.cpp llfloatersellland.cpp llfloatersettingsdebug.cpp llfloatersnapshot.cpp @@ -240,12 +241,15 @@ set(viewer_SOURCE_FILES llimpanel.cpp llimview.cpp llimcontrolpanel.cpp + llinspect.cpp llinspectavatar.cpp + llinspectgroup.cpp llinspectobject.cpp llinventorybridge.cpp llinventoryclipboard.cpp llinventoryfilter.cpp llinventorymodel.cpp + llinventorysubtreepanel.cpp lljoystickbutton.cpp lllandmarkactions.cpp lllandmarklist.cpp @@ -297,14 +301,7 @@ set(viewer_SOURCE_FILES llpanelblockedlist.cpp llpanelclassified.cpp llpanelcontents.cpp - llpaneldirbrowser.cpp - llpaneldirclassified.cpp - llpaneldirevents.cpp - llpaneldirfind.cpp - llpaneldirgroups.cpp - llpaneldirland.cpp - llpaneldirpeople.cpp - llpaneldirplaces.cpp + llpaneleditwearable.cpp llpanelevent.cpp llpanelface.cpp llpanelgroup.cpp @@ -345,6 +342,7 @@ set(viewer_SOURCE_FILES llpanelvolume.cpp llparcelselection.cpp llpatchvertexarray.cpp + llplacesinventorybridge.cpp llpolymesh.cpp llpolymorph.cpp llpreviewanim.cpp @@ -361,6 +359,7 @@ set(viewer_SOURCE_FILES llremoteparcelrequest.cpp llsavedsettingsglue.cpp llscreenchannel.cpp + llscrollingpanelparam.cpp llsearchcombobox.cpp llsearchhistory.cpp llselectmgr.cpp @@ -568,6 +567,7 @@ set(viewer_HEADER_FILES llchannelmanager.h llchatbar.h llchatitemscontainerctrl.h + llchathistory.h llchatmsgbox.h llchiclet.h llclassifiedinfo.h @@ -633,7 +633,6 @@ set(viewer_HEADER_FILES llfloatercolorpicker.h llfloatercustomize.h llfloaterdaycycle.h - llfloaterdirectory.h llfloaterenvsettings.h llfloaterfonttest.h llfloaterfriends.h @@ -669,6 +668,7 @@ set(viewer_HEADER_FILES llfloaterregioninfo.h llfloaterreporter.h llfloaterscriptdebug.h + llfloatersearch.h llfloatersellland.h llfloatersettingsdebug.h llfloatersnapshot.h @@ -714,11 +714,14 @@ set(viewer_HEADER_FILES llimview.h llimcontrolpanel.h llinspectavatar.h + llinspect.h + llinspectgroup.h llinspectobject.h llinventorybridge.h llinventoryclipboard.h llinventoryfilter.h llinventorymodel.h + llinventorysubtreepanel.h lljoystickbutton.h lllandmarkactions.h lllandmarklist.h @@ -767,14 +770,7 @@ set(viewer_HEADER_FILES llpanelblockedlist.h llpanelclassified.h llpanelcontents.h - llpaneldirbrowser.h - llpaneldirclassified.h - llpaneldirevents.h - llpaneldirfind.h - llpaneldirgroups.h - llpaneldirland.h - llpaneldirpeople.h - llpaneldirplaces.h + llpaneleditwearable.h llpanelevent.h llpanelface.h llpanelgroup.h @@ -815,6 +811,7 @@ set(viewer_HEADER_FILES llpanelvolume.h llparcelselection.h llpatchvertexarray.h + llplacesinventorybridge.h llpolymesh.h llpolymorph.h llpreview.h @@ -832,6 +829,7 @@ set(viewer_HEADER_FILES llresourcedata.h llrootview.h llscreenchannel.h + llscrollingpanelparam.h llsavedsettingsglue.h llsearchcombobox.h llsearchhistory.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f898c2d0c1..91d5e04665 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -7709,6 +7709,39 @@ <key>Value</key> <integer>1</integer> </map> + <key>FriendsSortOrder</key> + <map> + <key>Comment</key> + <string>Specifies sort order for friends (0 = by name, 1 = by online status)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>NearbyPeopleSortOrder</key> + <map> + <key>Comment</key> + <string>Specifies sort order for nearby people (0 = by name, 2 = by most recent)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>2</integer> + </map> + <key>RecentPeopleSortOrder</key> + <map> + <key>Comment</key> + <string>Specifies sort order for recent people (0 = by name, 2 = by most recent)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>2</integer> + </map> <key>ShowPGSearchAll</key> <map> <key>Comment</key> diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index c943c57fdb..f3bfa37cea 100644 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -1,310 +1,309 @@ <?xml version="1.0" encoding="US-ASCII" standalone="yes"?> <linden_avatar - version="1.0" - wearable_definition_version="22"> - <!-- The wearable_definition_version is checked during asset upload. --> - <!-- If you increment it, check indra/lib/python/indra/assetutil.py. --> - <skeleton - file_name="avatar_skeleton.xml"> - <attachment_point - id="1" - group="6" - pie_slice="2" - name="Chest" - joint="mChest" - position="0.15 0 -0.1" - rotation="0 90 90" - visible_in_first_person="true" /> - - <attachment_point - id="2" - group="2" - pie_slice="2" - name="Skull" - joint="mHead" - position="0 0 0.15" - rotation="0 0 90" - visible_in_first_person="false" /> - - <attachment_point - id="3" - group="3" - pie_slice="3" - name="Left Shoulder" - joint="mCollarLeft" - position="0 0 0.08" - rotation="0 0 0" - visible_in_first_person="true" /> + version="1.0" wearable_definition_version="23"> + <!-- The wearable_definition_version is checked during asset upload. --> + <!-- If you increment it, check indra/lib/python/indra/assetutil.py. --> + <skeleton + file_name="avatar_skeleton.xml"> + <attachment_point + id="1" + group="6" + pie_slice="2" + name="Chest" + joint="mChest" + position="0.15 0 -0.1" + rotation="0 90 90" + visible_in_first_person="true" /> - <attachment_point - id="4" - group="1" - pie_slice="1" - name="Right Shoulder" - joint="mCollarRight" - position="0 0 0.08" - rotation="0 0 0" - visible_in_first_person="true"/> - - <attachment_point - id="5" - group="4" - name="Left Hand" - joint="mWristLeft" - position="0 0.08 -0.02" - rotation="0 0 0" - visible_in_first_person="true" - max_attachment_offset="1.5" /> + <attachment_point + id="2" + group="2" + pie_slice="2" + name="Skull" + joint="mHead" + position="0 0 0.15" + rotation="0 0 90" + visible_in_first_person="false" /> - <attachment_point - id="6" - group="0" - name="Right Hand" - joint="mWristRight" - position="0 -0.08 -0.02" - rotation="0 0 0" - visible_in_first_person="true" - max_attachment_offset="1.5" /> - - <attachment_point - id="7" - group="5" - pie_slice="6" - name="Left Foot" - joint="mFootLeft" - position="0 0.0 0.0" - rotation="0 0 0" - visible_in_first_person="true"/> - - <attachment_point - id="8" - group="7" - pie_slice="6" - name="Right Foot" - joint="mFootRight" - position="0 0.0 0.0" - rotation="0 0 0" - visible_in_first_person="true"/> - - <attachment_point - id="9" - group="6" - pie_slice="7" - name="Spine" - joint="mChest" - position="-0.15 0 -0.1" - rotation="0 -90 90" - visible_in_first_person="true" /> - - <attachment_point - id="10" - group="6" - pie_slice="6" - name="Pelvis" - joint="mPelvis" - position="0 0 -0.15" - rotation="0 0 0" - visible_in_first_person="true" /> - - <attachment_point - id="11" - group="2" - pie_slice="6" - name="Mouth" - joint="mHead" - position="0.12 0 0.001" - rotation="0 0 0" - visible_in_first_person="false"/> - - <attachment_point - id="12" - group="2" - pie_slice="7" - name="Chin" - joint="mHead" - position="0.12 0 -0.04" - rotation="0 0 0" - visible_in_first_person="false" /> - - <attachment_point - id="13" - group="2" - pie_slice="4" - name="Left Ear" - joint="mHead" - position="0.015 0.08 0.017" - rotation="0 0 0" - visible_in_first_person="false" /> - - <attachment_point - id="14" - group="2" - pie_slice="0" - name="Right Ear" - joint="mHead" - position="0.015 -0.08 0.017" - rotation="0 0 0" - visible_in_first_person="false" /> - - <attachment_point - id="15" - group="2" - pie_slice="3" - name="Left Eyeball" - joint="mEyeLeft" - position="0 0 0" - rotation="0 0 0" - visible_in_first_person="false"/> - - <attachment_point - id="16" - group="2" - pie_slice="1" - name="Right Eyeball" - joint="mEyeRight" - position="0 0 0" - rotation="0 0 0" - visible_in_first_person="false" /> - - <attachment_point - id="17" - group="2" - pie_slice="5" - name="Nose" - joint="mHead" - position="0.1 0 0.05" - rotation="0 0 0" - visible_in_first_person="false"/> - - <attachment_point - id="18" - group="1" - pie_slice="0" - name="R Upper Arm" - joint="mShoulderRight" - position="0.01 -0.13 0.01" - rotation="0 0 0" - visible_in_first_person="true" /> + <attachment_point + id="3" + group="3" + pie_slice="3" + name="Left Shoulder" + joint="mCollarLeft" + position="0 0 0.08" + rotation="0 0 0" + visible_in_first_person="true" /> - <attachment_point - id="19" - group="1" - pie_slice="7" - name="R Forearm" - joint="mElbowRight" - position="0 -0.12 0" - rotation="0 0 0" - visible_in_first_person="true"/> - - <attachment_point - id="20" - group="3" - pie_slice="4" - name="L Upper Arm" - joint="mShoulderLeft" - position="0.01 0.15 -0.01" - rotation="0 0 0" - visible_in_first_person="true" /> - - <attachment_point - id="21" - group="3" - pie_slice="5" - name="L Forearm" - joint="mElbowLeft" - position="0 0.113 0" - rotation="0 0 0" - visible_in_first_person="true" /> - - <attachment_point - id="22" - group="7" - pie_slice="1" - name="Right Hip" - joint="mHipRight" - position="0 0 0" - rotation="0 0 0" - visible_in_first_person="true" /> - - <attachment_point - id="23" - group="7" - pie_slice="0" - name="R Upper Leg" - joint="mHipRight" - position="-0.017 0.041 -0.310" - rotation="0 0 0" - visible_in_first_person="true" /> - - <attachment_point - id="24" - group="7" - pie_slice="7" - name="R Lower Leg" - joint="mKneeRight" - position="-0.044 -0.007 -0.262" - rotation="0 0 0" - visible_in_first_person="true" /> - - <attachment_point - id="25" - group="5" - pie_slice="3" - name="Left Hip" - joint="mHipLeft" - position="0 0 0" - rotation="0 0 0" - visible_in_first_person="true" /> - - <attachment_point - id="26" - group="5" - pie_slice="4" - name="L Upper Leg" - joint="mHipLeft" - position="-0.019 -0.034 -0.310" - rotation="0 0 0" - visible_in_first_person="true"/> - - <attachment_point - id="27" - group="5" - pie_slice="5" - name="L Lower Leg" - joint="mKneeLeft" - position="-0.044 -0.007 -0.261" - rotation="0 0 0" - visible_in_first_person="true" /> - - <attachment_point - id="28" - group="6" - pie_slice="5" - name="Stomach" - joint="mPelvis" - position="0.092 0.0 0.088" - rotation="0 0 0" - visible_in_first_person="true" /> - - <attachment_point - id="29" - group="6" - pie_slice="3" - name="Left Pec" - joint="mTorso" - position="0.104 0.082 0.247" - rotation="0 0 0" - visible_in_first_person="true" /> - - <attachment_point - id="30" - group="6" - pie_slice="1" - name="Right Pec" - joint="mTorso" - position="0.104 -0.082 0.247" - rotation="0 0 0" - visible_in_first_person="true" /> + <attachment_point + id="4" + group="1" + pie_slice="1" + name="Right Shoulder" + joint="mCollarRight" + position="0 0 0.08" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="5" + group="4" + name="Left Hand" + joint="mWristLeft" + position="0 0.08 -0.02" + rotation="0 0 0" + visible_in_first_person="true" + max_attachment_offset="1.5" /> + + <attachment_point + id="6" + group="0" + name="Right Hand" + joint="mWristRight" + position="0 -0.08 -0.02" + rotation="0 0 0" + visible_in_first_person="true" + max_attachment_offset="1.5" /> + + <attachment_point + id="7" + group="5" + pie_slice="6" + name="Left Foot" + joint="mFootLeft" + position="0 0.0 0.0" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="8" + group="7" + pie_slice="6" + name="Right Foot" + joint="mFootRight" + position="0 0.0 0.0" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="9" + group="6" + pie_slice="7" + name="Spine" + joint="mChest" + position="-0.15 0 -0.1" + rotation="0 -90 90" + visible_in_first_person="true" /> + + <attachment_point + id="10" + group="6" + pie_slice="6" + name="Pelvis" + joint="mPelvis" + position="0 0 -0.15" + rotation="0 0 0" + visible_in_first_person="true" /> + + <attachment_point + id="11" + group="2" + pie_slice="6" + name="Mouth" + joint="mHead" + position="0.12 0 0.001" + rotation="0 0 0" + visible_in_first_person="false"/> + + <attachment_point + id="12" + group="2" + pie_slice="7" + name="Chin" + joint="mHead" + position="0.12 0 -0.04" + rotation="0 0 0" + visible_in_first_person="false" /> + + <attachment_point + id="13" + group="2" + pie_slice="4" + name="Left Ear" + joint="mHead" + position="0.015 0.08 0.017" + rotation="0 0 0" + visible_in_first_person="false" /> + + <attachment_point + id="14" + group="2" + pie_slice="0" + name="Right Ear" + joint="mHead" + position="0.015 -0.08 0.017" + rotation="0 0 0" + visible_in_first_person="false" /> + + <attachment_point + id="15" + group="2" + pie_slice="3" + name="Left Eyeball" + joint="mEyeLeft" + position="0 0 0" + rotation="0 0 0" + visible_in_first_person="false"/> + + <attachment_point + id="16" + group="2" + pie_slice="1" + name="Right Eyeball" + joint="mEyeRight" + position="0 0 0" + rotation="0 0 0" + visible_in_first_person="false" /> + + <attachment_point + id="17" + group="2" + pie_slice="5" + name="Nose" + joint="mHead" + position="0.1 0 0.05" + rotation="0 0 0" + visible_in_first_person="false"/> + + <attachment_point + id="18" + group="1" + pie_slice="0" + name="R Upper Arm" + joint="mShoulderRight" + position="0.01 -0.13 0.01" + rotation="0 0 0" + visible_in_first_person="true" /> + + <attachment_point + id="19" + group="1" + pie_slice="7" + name="R Forearm" + joint="mElbowRight" + position="0 -0.12 0" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="20" + group="3" + pie_slice="4" + name="L Upper Arm" + joint="mShoulderLeft" + position="0.01 0.15 -0.01" + rotation="0 0 0" + visible_in_first_person="true" /> + + <attachment_point + id="21" + group="3" + pie_slice="5" + name="L Forearm" + joint="mElbowLeft" + position="0 0.113 0" + rotation="0 0 0" + visible_in_first_person="true" /> + + <attachment_point + id="22" + group="7" + pie_slice="1" + name="Right Hip" + joint="mHipRight" + position="0 0 0" + rotation="0 0 0" + visible_in_first_person="true" /> + + <attachment_point + id="23" + group="7" + pie_slice="0" + name="R Upper Leg" + joint="mHipRight" + position="-0.017 0.041 -0.310" + rotation="0 0 0" + visible_in_first_person="true" /> + + <attachment_point + id="24" + group="7" + pie_slice="7" + name="R Lower Leg" + joint="mKneeRight" + position="-0.044 -0.007 -0.262" + rotation="0 0 0" + visible_in_first_person="true" /> + + <attachment_point + id="25" + group="5" + pie_slice="3" + name="Left Hip" + joint="mHipLeft" + position="0 0 0" + rotation="0 0 0" + visible_in_first_person="true" /> + + <attachment_point + id="26" + group="5" + pie_slice="4" + name="L Upper Leg" + joint="mHipLeft" + position="-0.019 -0.034 -0.310" + rotation="0 0 0" + visible_in_first_person="true"/> + + <attachment_point + id="27" + group="5" + pie_slice="5" + name="L Lower Leg" + joint="mKneeLeft" + position="-0.044 -0.007 -0.261" + rotation="0 0 0" + visible_in_first_person="true" /> + + <attachment_point + id="28" + group="6" + pie_slice="5" + name="Stomach" + joint="mPelvis" + position="0.092 0.0 0.088" + rotation="0 0 0" + visible_in_first_person="true" /> + + <attachment_point + id="29" + group="6" + pie_slice="3" + name="Left Pec" + joint="mTorso" + position="0.104 0.082 0.247" + rotation="0 0 0" + visible_in_first_person="true" /> + + <attachment_point + id="30" + group="6" + pie_slice="1" + name="Right Pec" + joint="mTorso" + position="0.104 -0.082 0.247" + rotation="0 0 0" + visible_in_first_person="true" /> <attachment_point id="31" @@ -394,6 +393,7 @@ max_attachment_offset="2.0" visible_in_first_person="true" /> + <param id="32" group="1" @@ -403,10899 +403,10959 @@ label_max="Male" value_min="0" value_max="1"> - <param_skeleton> - <bone - name="mNeck" - scale="0 0 .2" /> + <param_skeleton> + <bone + name="mNeck" + scale="0 0 .2" /> - <bone - name="mCollarLeft" - scale="0 .4 0" /> + <bone + name="mCollarLeft" + scale="0 .4 0" /> - <bone - name="mCollarRight" - scale="0 .4 0" /> + <bone + name="mCollarRight" + scale="0 .4 0" /> - <bone - name="mShoulderLeft" - scale="0 .35 0" /> + <bone + name="mShoulderLeft" + scale="0 .35 0" /> - <bone - name="mShoulderRight" - scale="0 .35 0" /> + <bone + name="mShoulderRight" + scale="0 .35 0" /> - <bone - name="mElbowLeft" - scale="0 .1 0" /> + <bone + name="mElbowLeft" + scale="0 .1 0" /> - <bone - name="mElbowRight" - scale="0 .1 0" /> + <bone + name="mElbowRight" + scale="0 .1 0" /> - <bone - name="mChest" - scale=".05 .05 .05" /> + <bone + name="mChest" + scale=".05 .05 .05" /> - <bone - name="mTorso" - scale="0 0 .05" /> + <bone + name="mTorso" + scale="0 0 .05" /> - <bone - name="mPelvis" - scale="0 0 0" /> + <bone + name="mPelvis" + scale="0 0 0" /> - <bone - name="mHipLeft" - scale=".05 .05 0" /> + <bone + name="mHipLeft" + scale=".05 .05 0" /> - <bone - name="mHipRight" - scale=".05 .05 0" /> + <bone + name="mHipRight" + scale=".05 .05 0" /> - <bone - name="mKneeLeft" - scale=".05 .05 .1" /> + <bone + name="mKneeLeft" + scale=".05 .05 .1" /> - <bone - name="mKneeRight" - scale=".05 .05 .1" /> - </param_skeleton> - </param> + <bone + name="mKneeRight" + scale=".05 .05 .1" /> + </param_skeleton> + </param> - <param - id="33" - group="0" - name="Height" - label="Height" - wearable="shape" - edit_group="shape_body" - edit_group_order="1" - label_min="Short" - label_max="Tall" - show_simple="true" - value_min="-2.3" - value_max="2" - camera_distance="2.2"> - <param_skeleton> - <bone - name="mNeck" - scale="0 0 .02" /> + <param + id="33" + group="0" + name="Height" + label="Height" + wearable="shape" + edit_group="shape_body" + edit_group_order="1" + label_min="Short" + label_max="Tall" + show_simple="true" + value_min="-2.3" + value_max="2" + camera_distance="2.2"> + <param_skeleton> + <bone + name="mNeck" + scale="0 0 .02" /> + + <bone + name="mCollarLeft" + scale="0 0 0" /> + + <bone + name="mCollarRight" + scale="0 0 0" /> + + <bone + name="mShoulderLeft" + scale="0 0.08 0" /> + + <bone + name="mShoulderRight" + scale="0 0.08 0" /> + + <bone + name="mElbowLeft" + scale="0 0.06 0" /> + + <bone + name="mElbowRight" + scale="0 0.06 0" /> + + <bone + name="mChest" + scale="0 0 0.05" /> + + <bone + name="mTorso" + scale="0 0 0.05" /> + + <bone + name="mPelvis" + scale="0 0 0" /> + + <bone + name="mHipLeft" + scale="0 0 0.1" /> + + <bone + name="mHipRight" + scale="0 0 0.1" /> + + <bone + name="mKneeLeft" + scale="0 0 0.1" /> + + <bone + name="mKneeRight" + scale="0 0 0.1" /> + </param_skeleton> + </param> - <bone - name="mCollarLeft" - scale="0 0 0" /> + <param + id="34" + group="0" + name="Thickness" + label="Body Thickness" + wearable="shape" + edit_group="shape_body" + edit_group_order="2" + label_min="Body Thin" + label_max="Body Thick" + show_simple="true" + value_min="-0.7" + value_max="1.5" + camera_distance="1.8"> + <param_skeleton> + <bone + name="mNeck" + scale="0.1 0.1 0" /> + + <bone + name="mCollarLeft" + scale="0 0.2 0" /> + + <bone + name="mCollarRight" + scale="0 0.2 0" /> + + <bone + name="mShoulderLeft" + scale="0.1 0 0.1" /> + + <bone + name="mShoulderRight" + scale="0.1 0 0.1" /> + + <bone + name="mElbowLeft" + scale="0.1 0 0.1" /> + + <bone + name="mElbowRight" + scale="0.1 0 0.1" /> + + <bone + name="mChest" + scale="0.1 0.1 0" /> + + <bone + name="mTorso" + scale="0.1 0.1 0" /> + + <bone + name="mPelvis" + scale="0.1 0.1 0" /> + + <bone + name="mHipLeft" + scale="0.13 0.13 0" /> + + <bone + name="mHipRight" + scale="0.13 0.13 0" /> + + <bone + name="mKneeLeft" + scale="0.12 0.12 0" /> + + <bone + name="mKneeRight" + scale="0.12 0.12 0" /> + </param_skeleton> + </param> - <bone - name="mCollarRight" - scale="0 0 0" /> + <param + id="36" + group="0" + name="Shoulders" + label="Shoulders" + wearable="shape" + edit_group="shape_torso" + edit_group_order="4" + label_min="Narrow" + label_max="Broad" + show_simple="true" + value_min="-1.8" + value_max="1.4" + value_default="-0.5" + camera_elevation=".1" + camera_distance="1.2" + camera_angle="0"> + <param_skeleton> + <bone + name="mNeck" + scale="0.01 0.03 0" /> + + <bone + name="mCollarLeft" + scale="0 0 0" + offset="0 .02 0" /> + + <bone + name="mCollarRight" + scale="0 0 0" + offset="0 -.02 0" /> + + <bone + name="mChest" + scale="0.02 0.08 0" /> + </param_skeleton> + </param> - <bone - name="mShoulderLeft" - scale="0 0.08 0" /> + <param + id="37" + group="0" + name="Hip Width" + label="Hip Width" + wearable="shape" + edit_group="shape_legs" + edit_group_order="3" + label_min="Narrow" + label_max="Wide" + show_simple="true" + value_min="-3.2" + value_max="2.8" + camera_distance="1.8"> + <param_skeleton> + <bone + name="mPelvis" + scale="0 0.1 0" /> + + <bone + name="mHipLeft" + scale="0 0 0" + offset="0 .004 0" /> + + <bone + name="mHipRight" + scale="0 0 0" + offset="0 -.004 0" /> + </param_skeleton> + </param> - <bone - name="mShoulderRight" - scale="0 0.08 0" /> + <param + id="842" + group="0" + name="Hip Length" + wearable="shape" + edit_group="shape_legs" + edit_group_order="3.2" + label_min="Short hips" + label_max="Long Hips" + value_min="-1" + value_max="1" + camera_distance="1.8"> + <param_skeleton> + <bone + name="mPelvis" + scale="0 0 0.3" /> + </param_skeleton> + </param> - <bone - name="mElbowLeft" - scale="0 0.06 0" /> + <param + id="38" + group="0" + name="Torso Length" + wearable="shape" + edit_group="shape_torso" + edit_group_order="11" + label_min="Short Torso" + label_max="Long Torso" + value_min="-1" + value_max="1" + camera_distance="1.8"> + <param_skeleton> + <bone + name="mTorso" + scale="0 0 .3" /> + + <bone + name="mPelvis" + scale="0 0 .1" /> + + <bone + name="mHipLeft" + scale="0 0 -.1" /> + + <bone + name="mHipRight" + scale="0 0 -.1" /> + + <bone + name="mKneeRight" + scale="0 0 -.05" /> + + <bone + name="mKneeLeft" + scale="0 0 -.05" /> + </param_skeleton> + </param> - <bone - name="mElbowRight" - scale="0 0.06 0" /> + <param + id="195" + group="1" + name="EyeBone_Spread" + wearable="shape" + edit_group="shape_eyes" + label_min="Eyes Together" + label_max="Eyes Spread" + value_min="-1" + value_max="1"> + <param_skeleton> + <bone + name="mEyeLeft" + scale="0 0 0" + offset="0 .009 0" /> + + <bone + name="mEyeRight" + scale="0 0 0" + offset="0 -.009 0" /> + </param_skeleton> + </param> - <bone - name="mChest" - scale="0 0 0.05" /> + <param + id="661" + group="1" + name="EyeBone_Head_Shear" + wearable="shape" + edit_group="shape_eyes" + label_min="Eyes Shear Left Up" + label_max="Eyes Shear Right Up" + value_min="-2" + value_max="2"> + <param_skeleton> + <bone + name="mEyeLeft" + scale="0 0 0" + offset="0 0 .004" /> + + <bone + name="mEyeRight" + scale="0 0 0" + offset="0 0 -.004" /> + </param_skeleton> + </param> - <bone - name="mTorso" - scale="0 0 0.05" /> + <param + id="772" + group="1" + name="EyeBone_Head_Elongate" + wearable="shape" + edit_group="shape_eyes" + label_min="Eyes Short Head" + label_max="Eyes Long Head" + value_min="-1" + value_max="1"> + <param_skeleton> + <bone + name="mEyeLeft" + scale="0 0 0" + offset=".016 0 0" /> + + <bone + name="mEyeRight" + scale="0 0 0" + offset=".016 0 0" /> + </param_skeleton> + </param> - <bone - name="mPelvis" - scale="0 0 0" /> + <param + id="768" + group="1" + name="EyeBone_Bug" + wearable="shape" + edit_group="shape_eyes" + label_min="Eyes Sunken" + label_max="Eyes Bugged" + value_min="-2" + value_max="2"> + <param_skeleton> + <bone + name="mEyeLeft" + scale="0 0 0" + offset=".005 0 0" /> + + <bone + name="mEyeRight" + scale="0 0 0" + offset=".005 0 0" /> + </param_skeleton> + </param> - <bone - name="mHipLeft" - scale="0 0 0.1" /> + <param + id="655" + group="1" + name="Head Size" + label="Head Size" + wearable="shape" + edit_group="shape_head" + label_min="Small Head" + label_max="Big Head" + show_simple="true" + value_min="-.25" + value_max=".10"> + <param_skeleton> + <bone + name="mSkull" + scale="1 1 1" + offset="0 0 0.1" /> + + <bone + name="mHead" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mEyeLeft" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mEyeRight" + scale="1 1 1" + offset="0 0 0" /> + </param_skeleton> + </param> - <bone - name="mHipRight" - scale="0 0 0.1" /> + <param + id="197" + group="1" + wearable="shoes" + name="Shoe_Heels" + edit_group="shoes" + label_min="No Heels" + label_max="High Heels" + value_min="0" + value_max="1"> + <param_skeleton> + <bone + name="mFootRight" + scale="0 0 0" + offset="0 0 -.08" /> + + <bone + name="mFootLeft" + scale="0 0 0" + offset="0 0 -.08" /> + </param_skeleton> + </param> - <bone - name="mKneeLeft" - scale="0 0 0.1" /> + <param + id="502" + group="1" + wearable="shoes" + name="Shoe_Platform" + edit_group="shoes" + label_min="No Heels" + label_max="High Heels" + value_min="0" + value_max="1"> + <param_skeleton> + <bone + name="mFootRight" + scale="0 0 0" + offset="0 0 -.07" /> + + <bone + name="mFootLeft" + scale="0 0 0" + offset="0 0 -.07" /> + </param_skeleton> + </param> - <bone - name="mKneeRight" - scale="0 0 0.1" /> - </param_skeleton> - </param> + <param + id="675" + group="0" + name="Hand Size" + wearable="shape" + edit_group="shape_torso" + edit_group_order="10" + label_min="Small Hands" + label_max="Large Hands" + value_min="-.3" + value_max=".3" + camera_elevation=".1" + camera_distance="1.4" + camera_angle="0"> + <param_skeleton> + <bone + name="mWristRight" + scale="1 1 1" + offset="0 0 0" /> + + <bone + name="mWristLeft" + scale="1 1 1" + offset="0 0 0" /> + </param_skeleton> + </param> - <param - id="34" - group="0" - name="Thickness" - label="Body Thickness" - wearable="shape" - edit_group="shape_body" - edit_group_order="2" - label_min="Body Thin" - label_max="Body Thick" - show_simple="true" - value_min="-0.7" - value_max="1.5" - camera_distance="1.8"> - <param_skeleton> - <bone - name="mNeck" - scale="0.1 0.1 0" /> + <param + id="683" + group="0" + name="Neck Thickness" + wearable="shape" + edit_group="shape_torso" + edit_group_order="2" + label_min="Skinny Neck" + label_max="Thick Neck" + value_min="-.4" + value_max=".2" + value_default="-.15" + camera_elevation=".3" + camera_distance=".8" + camera_angle="15"> + <param_skeleton> + <bone + name="mNeck" + scale="1 1 0" + offset="0 0 0" /> + </param_skeleton> + </param> - <bone - name="mCollarLeft" - scale="0 0.2 0" /> + <param + id="689" + group="1" + wearable="shape" + name="EyeBone_Big_Eyes" + edit_group="shape_eyes" + label_min="Eyes Back" + label_max="Eyes Forward" + value_min="-1" + value_max="1"> + <param_skeleton> + <bone + name="mEyeLeft" + scale="0 0 0" + offset="-.005 0 0" /> + + <bone + name="mEyeRight" + scale="0 0 0" + offset="-.005 0 0" /> + </param_skeleton> + </param> - <bone - name="mCollarRight" - scale="0 0.2 0" /> + <param + id="692" + group="0" + name="Leg Length" + wearable="shape" + edit_group="shape_legs" + edit_group_order="2" + label_min="Short Legs" + label_max="Long Legs" + value_min="-1" + value_max="1" + camera_distance="2.5"> + <param_skeleton> + <bone + name="mHipLeft" + scale="0 0 .2" /> + + <bone + name="mHipRight" + scale="0 0 .2" /> + + <bone + name="mKneeRight" + scale="0 0 .2" /> + + <bone + name="mKneeLeft" + scale="0 0 .2" /> + </param_skeleton> + </param> - <bone - name="mShoulderLeft" - scale="0.1 0 0.1" /> + <param + id="693" + group="0" + name="Arm Length" + wearable="shape" + edit_group="shape_torso" + edit_group_order="9" + label_min="Short Arms" + label_max="Long arms" + value_min="-1" + value_max="1" + value_default=".6" + camera_distance="1.5"> + <param_skeleton> + <bone + name="mShoulderLeft" + scale="0 .2 0" /> + + <bone + name="mShoulderRight" + scale="0 .2 0" /> + + <bone + name="mElbowRight" + scale="0 .3 0" /> + + <bone + name="mElbowLeft" + scale="0 .3 0" /> + </param_skeleton> + </param> - <bone - name="mShoulderRight" - scale="0.1 0 0.1" /> + <param + id="756" + group="0" + name="Neck Length" + wearable="shape" + edit_group="shape_torso" + edit_group_order="3" + label_min="Short Neck" + label_max="Long Neck" + value_min="-1" + value_max="1" + value_default="0" + camera_elevation=".3" + camera_distance=".8" + camera_angle="15"> + <param_skeleton> + <bone + name="mNeck" + scale="0 0 .5" /> + </param_skeleton> + </param> + </skeleton> + + <mesh + type="hairMesh" + lod="0" + file_name="avatar_hair.llm" + min_pixel_width="320"> + <!-- begin morph targets --> + <param + id="180" + group="1" + name="Hair_Volume" + label="Hair Volume" + show_simple="true" + wearable="hair" + clothing_morph="true" + edit_group="hair_style" + label_min="Less" + label_max="More" + value_min="0" + value_max="1.3" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> - <bone - name="mElbowLeft" - scale="0.1 0 0.1" /> + <param + id="761" + group="1" + name="Hair_Volume_Small" + label="Hair Volume" + show_simple="true" + wearable="hair" + edit_group="hair_style" + label_min="Less" + label_max="More" + value_min="0" + value_max="1.3" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> - <bone - name="mElbowRight" - scale="0.1 0 0.1" /> + <param + id="181" + group="0" + name="Hair_Big_Front" + label="Big Hair Front" + wearable="hair" + edit_group="hair_style" + edit_group_order="5" + label_min="Less" + label_max="More" + value_min="-1" + value_max="1" + value_default="0.14" + camera_elevation=".1" + camera_distance=".5" + camera_angle="90"> + <param_morph /> + </param> - <bone - name="mChest" - scale="0.1 0.1 0" /> + <param + id="182" + group="0" + name="Hair_Big_Top" + label="Big Hair Top" + wearable="hair" + edit_group="hair_style" + edit_group_order="6" + label_min="Less" + label_max="More" + value_min="-1" + value_max="1" + value_default=".7" + camera_elevation=".1" + camera_distance=".5" + camera_angle="90"> + <param_morph /> + </param> - <bone - name="mTorso" - scale="0.1 0.1 0" /> + <param + id="183" + group="0" + name="Hair_Big_Back" + clothing_morph="true" + label="Big Hair Back" + wearable="hair" + edit_group="hair_style" + edit_group_order="7" + label_min="Less" + label_max="More" + value_min="-1" + value_max="1" + value_default="0.05" + camera_elevation=".1" + camera_distance=".7" + camera_angle="90"> + <param_morph /> + </param> - <bone - name="mPelvis" - scale="0.1 0.1 0" /> + <param + id="184" + group="0" + name="Hair_Spiked" + label="Spiked Hair" + show_simple="true" + wearable="hair" + clothing_morph="true" + edit_group="hair_style" + edit_group_order="15" + label_min="No Spikes" + label_max="Big Spikes" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> - <bone - name="mHipLeft" - scale="0.13 0.13 0" /> + <param + id="140" + group="0" + name="Hair_Part_Middle" + label="Middle Part" + wearable="hair" + edit_group="hair_style" + edit_group_order="17" + label_min="No Part" + label_max="Part" + value_min="0" + value_max="2" + camera_elevation=".1" + camera_distance=".5" + camera_angle="0"> + <param_morph /> + </param> - <bone - name="mHipRight" - scale="0.13 0.13 0" /> + <param + id="141" + group="0" + name="Hair_Part_Right" + label="Right Part" + wearable="hair" + edit_group="hair_style" + edit_group_order="18" + label_min="No Part" + label_max="Part" + value_min="0" + value_max="2" + camera_elevation=".1" + camera_distance=".5" + camera_angle="0"> + <param_morph /> + </param> - <bone - name="mKneeLeft" - scale="0.12 0.12 0" /> + <param + id="142" + group="0" + name="Hair_Part_Left" + label="Left Part" + wearable="hair" + edit_group="hair_style" + edit_group_order="19" + label_min="No Part" + label_max="Part" + value_min="0" + value_max="2" + camera_elevation=".1" + camera_distance=".5" + camera_angle="0"> + <param_morph /> + </param> - <bone - name="mKneeRight" - scale="0.12 0.12 0" /> - </param_skeleton> - </param> + <param + id="143" + group="0" + name="Hair_Sides_Full" + label="Full Hair Sides" + show_simple="true" + wearable="hair" + edit_group="hair_style" + edit_group_order="11" + label_min="Mowhawk" + label_max="Full Sides" + value_min="-4" + value_max="1.5" + value_default="0.125" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> - <param - id="36" - group="0" - name="Shoulders" - label="Shoulders" - wearable="shape" - edit_group="shape_torso" - edit_group_order="4" - label_min="Narrow" - label_max="Broad" - show_simple="true" - value_min="-1.8" - value_max="1.4" - value_default="-0.5" - camera_elevation=".1" - camera_distance="1.2" - camera_angle="0"> - <param_skeleton> - <bone - name="mNeck" - scale="0.01 0.03 0" /> + <param + id="144" + group="1" + name="Bangs_Front_Up" + label="Front Bangs Up" + wearable="hair" + edit_group="hair_style" + label_min="Bangs" + label_max="Bangs Up" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> - <bone - name="mCollarLeft" - scale="0 0 0" - offset="0 .02 0" /> + <param + id="145" + group="1" + clothing_morph="true" + name="Bangs_Front_Down" + label="Front Bangs Down" + wearable="hair" + edit_group="hair_style" + label_min="Bangs" + label_max="Bangs Down" + value_min="0" + value_max="5" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> - <bone - name="mCollarRight" - scale="0 0 0" - offset="0 -.02 0" /> + <param + id="146" + group="1" + name="Bangs_Sides_Up" + label="Side Bangs Up" + wearable="hair" + edit_group="hair_style" + label_min="Side Bangs" + label_max="Side Bangs Up" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> - <bone - name="mChest" - scale="0.02 0.08 0" /> - </param_skeleton> - </param> + <param + id="147" + group="1" + clothing_morph="true" + name="Bangs_Sides_Down" + label="Side Bangs Down" + wearable="hair" + edit_group="hair_style" + label_min="Side Bangs" + label_max="Side Bangs Down" + value_min="0" + value_max="2" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> - <param - id="37" - group="0" - name="Hip Width" - label="Hip Width" - wearable="shape" - edit_group="shape_legs" - edit_group_order="3" - label_min="Narrow" - label_max="Wide" - show_simple="true" - value_min="-3.2" - value_max="2.8" - camera_distance="1.8"> - <param_skeleton> - <bone - name="mPelvis" - scale="0 0.1 0" /> - - <bone - name="mHipLeft" - scale="0 0 0" - offset="0 .004 0" /> - - <bone - name="mHipRight" - scale="0 0 0" - offset="0 -.004 0" /> - </param_skeleton> - </param> - - <param - id="842" - group="0" - name="Hip Length" - wearable="shape" - edit_group="shape_legs" - edit_group_order="3.2" - label_min="Short hips" - label_max="Long Hips" - value_min="-1" - value_max="1" - camera_distance="1.8"> - <param_skeleton> - <bone - name="mPelvis" - scale="0 0 0.3" /> - </param_skeleton> - </param> + <param + id="148" + group="1" + name="Bangs_Back_Up" + label="Back Bangs Up" + wearable="hair" + edit_group="hair_style" + label_min="Back Bangs" + label_max="Back Bangs Up" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="150"> + <param_morph /> + </param> - <param - id="38" - group="0" - name="Torso Length" - wearable="shape" - edit_group="shape_torso" - edit_group_order="11" - label_min="Short Torso" - label_max="Long Torso" - value_min="-1" - value_max="1" - camera_distance="1.8"> - <param_skeleton> - <bone - name="mTorso" - scale="0 0 .3" /> + <param + id="149" + group="1" + name="Bangs_Back_Down" + label="Back Bangs Down" + clothing_morph="true" + wearable="hair" + edit_group="hair_style" + label_min="Back Bangs" + label_max="Back Bangs Down" + value_min="0" + value_max="2" + camera_elevation=".1" + camera_distance=".5" + camera_angle="150"> + <param_morph /> + </param> - <bone - name="mPelvis" - scale="0 0 .1" /> + <param + id="171" + group="1" + name="Hair_Front_Down" + label="Front Hair Down" + wearable="hair" + edit_group="hair_style" + label_min="Front Hair" + label_max="Front Hair Down" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> - <bone - name="mHipLeft" - scale="0 0 -.1" /> + <param + id="172" + group="1" + name="Hair_Front_Up" + label="Front Hair Up" + wearable="hair" + edit_group="hair_style" + label_min="Front Hair" + label_max="Front Hair Up" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> - <bone - name="mHipRight" - scale="0 0 -.1" /> + <param + id="173" + group="1" + name="Hair_Sides_Down" + label="Sides Hair Down" + wearable="hair" + edit_group="hair_style" + label_min="Sides Hair" + label_max="Sides Hair Down" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> - <bone - name="mKneeRight" - scale="0 0 -.05" /> + <param + id="174" + group="1" + name="Hair_Sides_Up" + label="Sides Hair Up" + wearable="hair" + edit_group="hair_style" + label_min="Sides Hair" + label_max="Sides Hair Up" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> - <bone - name="mKneeLeft" - scale="0 0 -.05" /> - </param_skeleton> - </param> + <param + id="175" + group="1" + name="Hair_Back_Down" + label="Back Hair Down" + clothing_morph="true" + wearable="hair" + edit_group="hair_style" + label_min="Back Hair" + label_max="Back Hair Down" + value_min="0" + value_max="3" + camera_elevation=".1" + camera_distance=".5" + camera_angle="150"> + <param_morph /> + </param> - <param - id="195" - group="1" - name="EyeBone_Spread" - wearable="shape" - edit_group="shape_eyes" - label_min="Eyes Together" - label_max="Eyes Spread" - value_min="-1" - value_max="1"> - <param_skeleton> - <bone - name="mEyeLeft" - scale="0 0 0" - offset="0 .009 0" /> + <param + id="176" + group="1" + name="Hair_Back_Up" + label="Back Hair Up" + wearable="hair" + edit_group="hair_style" + label_min="Back Hair" + label_max="Back Hair Up" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="150"> + <param_morph /> + </param> - <bone - name="mEyeRight" - scale="0 0 0" - offset="0 -.009 0" /> - </param_skeleton> - </param> + <param + id="177" + group="0" + name="Hair_Rumpled" + label="Rumpled Hair" + show_simple="true" + wearable="hair" + clothing_morph="true" + edit_group="hair_style" + edit_group_order="14.5" + label_min="Smooth Hair" + label_max="Rumpled Hair" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> - <param - id="661" - group="1" - name="EyeBone_Head_Shear" - wearable="shape" - edit_group="shape_eyes" - label_min="Eyes Shear Left Up" - label_max="Eyes Shear Right Up" - value_min="-2" - value_max="2"> - <param_skeleton> - <bone - name="mEyeLeft" - scale="0 0 0" - offset="0 0 .004" /> + <param + id="178" + group="1" + name="Hair_Swept_Back" + label="Swept Back Hair" + wearable="hair" + edit_group="hair_style" + label_min="NotHair" + label_max="Swept Back" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="90"> + <param_morph /> + </param> - <bone - name="mEyeRight" - scale="0 0 0" - offset="0 0 -.004" /> - </param_skeleton> - </param> + <param + id="179" + group="1" + name="Hair_Swept_Forward" + label="Swept Forward Hair" + wearable="hair" + edit_group="hair_style" + label_min="Hair" + label_max="Swept Forward" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="90"> + <param_morph /> + </param> - <param - id="772" - group="1" - name="EyeBone_Head_Elongate" - wearable="shape" - edit_group="shape_eyes" - label_min="Eyes Short Head" - label_max="Eyes Long Head" - value_min="-1" - value_max="1"> - <param_skeleton> - <bone - name="mEyeLeft" - scale="0 0 0" - offset=".016 0 0" /> + <param + id="190" + group="1" + name="Hair_Tilt_Right" + label="Hair Tilted Right" + wearable="hair" + edit_group="hair_style" + label_min="Hair" + label_max="Tilt Right" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="0"> + <param_morph /> + </param> - <bone - name="mEyeRight" - scale="0 0 0" - offset=".016 0 0" /> - </param_skeleton> - </param> + <param + id="191" + group="1" + name="Hair_Tilt_Left" + label="Hair Tilted Left" + wearable="hair" + edit_group="hair_style" + label_min="Hair" + label_max="Tilt Left" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="0"> + <param_morph /> + </param> - <param - id="768" - group="1" - name="EyeBone_Bug" - wearable="shape" - edit_group="shape_eyes" - label_min="Eyes Sunken" - label_max="Eyes Bugged" - value_min="-2" - value_max="2"> - <param_skeleton> - <bone - name="mEyeLeft" - scale="0 0 0" - offset=".005 0 0" /> + <param + id="192" + group="0" + name="Bangs_Part_Middle" + label="Part Bangs" + wearable="hair" + edit_group="hair_style" + edit_group_order="20" + label_min="No Part" + label_max="Part Bangs" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="0"> + <param_morph /> + </param> - <bone - name="mEyeRight" - scale="0 0 0" - offset=".005 0 0" /> - </param_skeleton> - </param> + <param + id="640" + group="1" + name="Hair_Egg_Head" + wearable="hair" + edit_group="hair_style" + cross_wearable="true" + value_min="-1.3" + value_max="1"> + <param_morph /> + </param> - <param - id="655" - group="1" - name="Head Size" - label="Head Size" - wearable="shape" - edit_group="shape_head" - label_min="Small Head" - label_max="Big Head" - show_simple="true" - value_min="-.25" - value_max=".10"> - <param_skeleton> - <bone - name="mSkull" - scale="1 1 1" - offset="0 0 0.1" /> - - <bone - name="mHead" - scale="1 1 1" - offset="0 0 0" /> - - <bone - name="mEyeLeft" - scale="1 1 1" - offset="0 0 0" /> - - <bone - name="mEyeRight" - scale="1 1 1" - offset="0 0 0" /> - </param_skeleton> - </param> - - <param - id="197" - group="1" - wearable="shoes" - name="Shoe_Heels" - edit_group="shoes" - label_min="No Heels" - label_max="High Heels" - value_min="0" - value_max="1"> - <param_skeleton> - <bone - name="mFootRight" - scale="0 0 0" - offset="0 0 -.08" /> + <param + id="641" + group="1" + name="Hair_Squash_Stretch_Head" + wearable="hair" + edit_group="hair_style" + cross_wearable="true" + value_min="-.5" + value_max="1"> + <param_morph /> + </param> - <bone - name="mFootLeft" - scale="0 0 0" - offset="0 0 -.08" /> - </param_skeleton> - </param> + <param + id="642" + group="1" + name="Hair_Square_Head" + wearable="hair" + edit_group="hair_style" + cross_wearable="true" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="502" - group="1" - wearable="shoes" - name="Shoe_Platform" - edit_group="shoes" - label_min="No Heels" - label_max="High Heels" - value_min="0" - value_max="1"> - <param_skeleton> - <bone - name="mFootRight" - scale="0 0 0" - offset="0 0 -.07" /> + <param + id="643" + group="1" + name="Hair_Round_Head" + wearable="hair" + edit_group="hair_style" + cross_wearable="true" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <bone - name="mFootLeft" - scale="0 0 0" - offset="0 0 -.07" /> - </param_skeleton> - </param> + <param + id="644" + group="1" + name="Hair_Forehead_Round" + wearable="hair" + edit_group="hair_style" + cross_wearable="true" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="675" - group="0" - name="Hand Size" - wearable="shape" - edit_group="shape_torso" - edit_group_order="10" - label_min="Small Hands" - label_max="Large Hands" - value_min="-.3" - value_max=".3" - camera_elevation=".1" - camera_distance="1.4" - camera_angle="0"> - <param_skeleton> - <bone - name="mWristRight" - scale="1 1 1" - offset="0 0 0" /> + <param + id="645" + group="1" + name="Hair_Forehead_Slant" + wearable="hair" + edit_group="hair_style" + cross_wearable="true" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <bone - name="mWristLeft" - scale="1 1 1" - offset="0 0 0" /> - </param_skeleton> - </param> + <param + id="774" + group="1" + name="Shear_Head_Hair" + wearable="hair" + edit_group="hair_style" + cross_wearable="true" + value_min="-2" + value_max="2"> + <param_morph /> + </param> - <param - id="683" - group="0" - name="Neck Thickness" - wearable="shape" - edit_group="shape_torso" - edit_group_order="2" - label_min="Skinny Neck" - label_max="Thick Neck" - value_min="-.4" - value_max=".2" - value_default="-.15" - camera_elevation=".3" - camera_distance=".8" - camera_angle="15"> - <param_skeleton> - <bone - name="mNeck" - scale="1 1 0" - offset="0 0 0" /> - </param_skeleton> - </param> - - <param - id="689" - group="1" - wearable="shape" - name="EyeBone_Big_Eyes" - edit_group="shape_eyes" - label_min="Eyes Back" - label_max="Eyes Forward" - value_min="-1" - value_max="1"> - <param_skeleton> - <bone - name="mEyeLeft" - scale="0 0 0" - offset="-.005 0 0" /> + <param + id="771" + group="1" + name="Elongate_Head_Hair" + wearable="hair" + edit_group="hair_style" + cross_wearable="true" + value_min="-1" + value_max="1"> + <param_morph /> + </param> - <bone - name="mEyeRight" - scale="0 0 0" - offset="-.005 0 0" /> - </param_skeleton> - </param> + <param + id="674" + group="0" + name="Hair_Shear_Back" + wearable="hair" + edit_group="hair_style" + edit_group_order="12" + label="Shear Back" + label_min="Full Back" + label_max="Sheared Back" + value_min="-1" + value_max="2" + value_default="-0.3" + camera_elevation=".1" + camera_distance=".5" + camera_angle="100"> + <param_morph /> + </param> - <param - id="692" - group="0" - name="Leg Length" - wearable="shape" - edit_group="shape_legs" - edit_group_order="2" - label_min="Short Legs" - label_max="Long Legs" - value_min="-1" - value_max="1" - camera_distance="2.5"> - <param_skeleton> - <bone - name="mHipLeft" - scale="0 0 .2" /> + <param + id="762" + group="0" + name="Hair_Shear_Front" + wearable="hair" + edit_group="hair_style" + edit_group_order="11.8" + label="Shear Front" + show_simple="true" + label_min="Full Front" + label_max="Sheared Front" + value_min="0" + value_max="3" + camera_elevation=".1" + camera_distance=".5" + camera_angle="30"> + <param_morph /> + </param> - <bone - name="mHipRight" - scale="0 0 .2" /> + <param + id="754" + group="0" + name="Hair_Taper_Back" + wearable="hair" + edit_group="hair_style" + edit_group_order="14" + label="Taper Back" + label_min="Wide Back" + label_max="Narrow Back" + value_min="-1" + value_max="2" + value_default="0" + camera_elevation=".1" + camera_distance=".5" + camera_angle="160"> + <param_morph /> + </param> - <bone - name="mKneeRight" - scale="0 0 .2" /> + <param + id="755" + group="0" + name="Hair_Taper_Front" + wearable="hair" + edit_group="hair_style" + edit_group_order="13" + label="Taper Front" + label_min="Wide Front" + label_max="Narrow Front" + value_min="-1.5" + value_max="1.5" + value_default="0.05" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> - <bone - name="mKneeLeft" - scale="0 0 .2" /> - </param_skeleton> - </param> + <param + id="782" + group="1" + clothing_morph="true" + name="Hair_Pigtails_Short" + wearable="hair" + edit_group="hair_style" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="693" - group="0" - name="Arm Length" - wearable="shape" - edit_group="shape_torso" - edit_group_order="9" - label_min="Short Arms" - label_max="Long arms" - value_min="-1" - value_max="1" - value_default=".6" - camera_distance="1.5"> - <param_skeleton> - <bone - name="mShoulderLeft" - scale="0 .2 0" /> + <param + id="783" + group="1" + clothing_morph="true" + name="Hair_Pigtails_Med" + wearable="hair" + edit_group="hair_style" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <bone - name="mShoulderRight" - scale="0 .2 0" /> + <param + id="790" + group="1" + clothing_morph="true" + name="Hair_Pigtails_Medlong" + wearable="hair" + edit_group="hair_style" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <bone - name="mElbowRight" - scale="0 .3 0" /> + <param + id="784" + group="1" + clothing_morph="true" + name="Hair_Pigtails_Long" + wearable="hair" + edit_group="hair_style" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <bone - name="mElbowLeft" - scale="0 .3 0" /> - </param_skeleton> - </param> + <param + id="786" + group="1" + name="Hair_Ponytail_Short" + wearable="hair" + edit_group="hair_style" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="756" + <param + id="787" + group="1" + name="Hair_Ponytail_Med" + wearable="hair" + edit_group="hair_style" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="788" + group="1" + name="Hair_Ponytail_Long" + clothing_morph="true" + wearable="hair" + edit_group="hair_style" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <!-- #end morph targets --> + </mesh> + + <mesh + type="hairMesh" + lod="1" + file_name="avatar_hair_1.llm" + min_pixel_width="160" + reference="avatar_hair.llm"> + </mesh> + + <mesh + type="hairMesh" + lod="2" + file_name="avatar_hair_2.llm" + min_pixel_width="80" + reference="avatar_hair.llm"> + </mesh> + + <mesh + type="hairMesh" + lod="3" + file_name="avatar_hair_3.llm" + min_pixel_width="40" + reference="avatar_hair.llm"> + </mesh> + + <mesh + type="hairMesh" + lod="4" + file_name="avatar_hair_4.llm" + min_pixel_width="20" + reference="avatar_hair.llm"> + </mesh> + + <mesh + type="hairMesh" + lod="5" + file_name="avatar_hair_5.llm" + min_pixel_width="0" + reference="avatar_hair.llm"> + </mesh> + + <mesh + type="headMesh" + lod="0" + file_name="avatar_head.llm" + min_pixel_width="320"> + <!-- + begin morph targets + ############# + tweakable morphs + ############# + --> + <param + id="1" + group="0" + name="Big_Brow" + label="Brow Size" + wearable="shape" + edit_group="shape_head" + edit_group_order="7" + label_min="Small" + label_max="Large" + value_min="-.3" + value_max="2" + camera_elevation=".1" + camera_distance=".4" + camera_angle="45"> + <param_morph /> + </param> + + <param + id="2" + group="0" + name="Nose_Big_Out" + label="Nose Size" + wearable="shape" + edit_group="shape_nose" + edit_group_order="1" + label_min="Small" + label_max="Large" + show_simple="true" + value_min="-0.8" + value_max="2.5" + camera_elevation=".1" + camera_distance=".35" + camera_angle="50"> + <param_morph /> + </param> + + <param + id="4" + group="0" + name="Broad_Nostrils" + label="Nostril Width" + wearable="shape" + edit_group="shape_nose" + edit_group_order="3" + label_min="Narrow" + label_max="Broad" + value_min="-.5" + value_max="1" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_morph /> + </param> + + <param + id="759" + group="0" + name="Low_Septum_Nose" + label="Nostril Division" + wearable="shape" + edit_group="shape_nose" + edit_group_order="3.5" + label_min="High" + label_max="Low" + value_min="-1" + value_max="1.5" + value_default="0.5" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_morph /> + </param> + + <param + id="517" + group="0" + name="Wide_Nose" + label="Nose Width" + wearable="shape" + edit_group="shape_nose" + edit_group_order="2" + label_min="Narrow" + label_max="Wide" + show_simple="true" + value_min="-.5" + value_max="1" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_morph /> + </param> + + <param + id="5" + group="0" + name="Cleft_Chin" + label="Chin Cleft" + wearable="shape" + edit_group="shape_chin" + edit_group_order="6" + label_min="Round" + label_max="Cleft" + value_min="-.1" + value_max="1" + camera_elevation="0" + camera_distance=".28" + camera_angle="-20"> + <param_morph /> + </param> + + <param + id="6" + group="0" + name="Bulbous_Nose_Tip" + label="Nose Tip Shape" + wearable="shape" + edit_group="shape_nose" + edit_group_order="8" + label_min="Pointy" + label_max="Bulbous" + value_min="-.3" + value_max="1" + camera_elevation=".1" + camera_distance=".35" + camera_angle="15"> + <param_morph /> + </param> + + <param + id="7" + group="0" + name="Weak_Chin" + label="Chin Angle" + wearable="shape" + edit_group="shape_chin" + edit_group_order="1" + label_min="Chin Out" + label_max="Chin In" + value_min="-.5" + value_max=".5" + camera_elevation=".1" + camera_distance=".4" + camera_angle="45"> + <param_morph /> + </param> + + <param + id="8" + group="0" + name="Double_Chin" + label="Chin-Neck" + wearable="shape" + edit_group="shape_chin" + edit_group_order="8" + label_min="Tight Chin" + label_max="Double Chin" + value_min="-.5" + value_max="1.5" + camera_elevation="-.1" + camera_distance=".3" + camera_angle="60"> + <param_morph /> + </param> + + <param + id="10" + group="0" + name="Sunken_Cheeks" + label="Lower Cheeks" + wearable="shape" + edit_group="shape_head" + edit_group_order="9" + label_min="Well-Fed" + label_max="Sunken" + show_simple="true" + value_min="-1.5" + value_max="3" + camera_elevation=".1" + camera_distance=".4" + camera_angle="5"> + <param_morph /> + </param> + + <param + id="11" + group="0" + name="Noble_Nose_Bridge" + label="Upper Bridge" + wearable="shape" + edit_group="shape_nose" + edit_group_order="5" + label_min="Low" + label_max="High" + value_min="-.5" + value_max="1.5" + camera_elevation=".1" + camera_distance=".35" + camera_angle="70"> + <param_morph /> + </param> + + <param + id="758" + group="0" + name="Lower_Bridge_Nose" + label="Lower Bridge" + wearable="shape" + edit_group="shape_nose" + edit_group_order="5.5" + label_min="Low" + label_max="High" + value_min="-1.5" + value_max="1.5" + camera_elevation=".1" + camera_distance=".35" + camera_angle="70"> + <param_morph /> + </param> + + <param + id="12" + group="0" + name="Jowls" + wearable="shape" + edit_group="shape_chin" + edit_group_order="5" + label_min="Less" + label_max="More" + value_min="-.5" + value_max="2.5" + camera_elevation=".1" + camera_distance=".4" + camera_angle="0"> + <param_morph /> + </param> + + <param + id="13" + group="0" + name="Cleft_Chin_Upper" + label="Upper Chin Cleft" + wearable="shape" + edit_group="shape_chin" + edit_group_order="7" + label_min="Round" + label_max="Cleft" + value_min="0" + value_max="1.5" + camera_elevation="0" + camera_distance=".28" + camera_angle="-20"> + <param_morph /> + </param> + + <param + id="14" + group="0" + name="High_Cheek_Bones" + label="Cheek Bones" + wearable="shape" + edit_group="shape_head" + edit_group_order="10" + label_min="Low" + label_max="High" + value_min="-.5" + value_max="1" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_morph /> + </param> + + <param + id="15" + group="0" + name="Ears_Out" + label="Ear Angle" + wearable="shape" + edit_group="shape_ears" + edit_group_order="2" + label_min="In" + label_max="Out" + value_min="-.5" + value_max="1.5" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_morph /> + </param> + + <!--Pointy eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1--> + <param + id="870" + group="1" + name="Pointy_Eyebrows" + label="Eyebrow Points" + wearable="hair" + edit_group="hair_eyebrows" + edit_group_order="4" + label_min="Smooth" + label_max="Pointy" + value_min="-.5" + value_max="1" + camera_elevation=".1" + camera_distance=".3"> + <param_morph /> + </param> + + <param + id="17" + group="0" + name="Square_Jaw" + label="Jaw Shape" + wearable="shape" + edit_group="shape_chin" + edit_group_order="2" + label_min="Pointy" + label_max="Square" + value_min="-.5" + value_max="1" + camera_distance=".3" + camera_elevation=".04" + camera_angle="-20"> + <param_morph /> + </param> + + <param + id="18" + group="0" + name="Puffy_Upper_Cheeks" + label="Upper Cheeks" + wearable="shape" + edit_group="shape_head" + edit_group_order="8" + label_min="Thin" + label_max="Puffy" + value_min="-1.5" + value_max="2.5" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_morph /> + </param> + + <param + id="19" + group="0" + name="Upturned_Nose_Tip" + label="Nose Tip Angle" + wearable="shape" + edit_group="shape_nose" + edit_group_order="7" + label_min="Downturned" + label_max="Upturned" + value_min="-1.5" + value_max="1" + camera_elevation=".1" + camera_distance=".35" + camera_angle="15"> + <param_morph /> + </param> + + <param + id="20" + group="0" + name="Bulbous_Nose" + label="Nose Thickness" + wearable="shape" + edit_group="shape_nose" + edit_group_order="4" + label_min="Thin Nose" + label_max="Bulbous Nose" + show_simple="true" + value_min="-.5" + value_max="1.5" + camera_elevation=".1" + camera_distance=".3"> + <param_morph /> + </param> + + <param + id="21" + group="0" + name="Upper_Eyelid_Fold" + label="Upper Eyelid Fold" + wearable="shape" + edit_group="shape_eyes" + edit_group_order="5" + label_min="Uncreased" + label_max="Creased" + value_min="-0.2" + value_max="1.3" + camera_elevation=".1" + camera_distance=".35"> + <param_morph /> + </param> + + <param + id="22" + group="0" + name="Attached_Earlobes" + label="Attached Earlobes" + wearable="shape" + edit_group="shape_ears" + edit_group_order="3" + label_min="Unattached" + label_max="Attached" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".3" + camera_angle="45"> + <param_morph /> + </param> + + <param + id="23" + group="0" + name="Baggy_Eyes" + label="Eye Bags" + wearable="shape" + edit_group="shape_eyes" + edit_group_order="6" + label_min="Smooth" + label_max="Baggy" + value_min="-.5" + value_max="1.5" + camera_elevation=".1" + camera_distance=".35"> + <param_morph /> + </param> + + <param + id="765" + group="0" + name="Puffy_Lower_Lids" + label="Puffy Eyelids" + wearable="shape" + edit_group="shape_eyes" + edit_group_order="6.1" + label_min="Flat" + label_max="Puffy" + value_min="-.3" + value_max="2.5" + camera_elevation=".1" + camera_distance=".35"> + <param_morph /> + </param> + + <param + id="24" + group="0" + name="Wide_Eyes" + label="Eye Opening" + wearable="shape" + edit_group="shape_eyes" + edit_group_order="1.1" + label_min="Narrow" + label_max="Wide" + value_min="-1.5" + value_max="2" + show_simple="true" + camera_elevation=".1" + camera_distance=".35"> + <param_morph /> + </param> + + <param + id="25" + group="0" + name="Wide_Lip_Cleft" + label="Lip Cleft" + wearable="shape" + edit_group="shape_mouth" + edit_group_order="6" + label_min="Narrow" + label_max="Wide" + value_min="-.8" + value_max="1.5" + camera_elevation="0" + camera_distance=".28"> + <param_morph /> + </param> + + <param + id="764" + group="0" + name="Lip_Cleft_Deep" + label="Lip Cleft Depth" + wearable="shape" + edit_group="shape_mouth" + edit_group_order="5.8" + label_min="Shallow" + label_max="Deep" + value_min="-.5" + value_max="1.2" + camera_elevation="0" + camera_distance=".28"> + <param_morph /> + </param> + + <param + id="26" + group="1" + wearable="shape" + name="Lips_Thin" + edit_group="driven" + value_min="0" + value_max=".7"> + <param_morph /> + </param> + + <param + id="27" + group="0" + name="Wide_Nose_Bridge" + label="Bridge Width" + wearable="shape" + edit_group="shape_nose" + edit_group_order="6" + label_min="Narrow" + label_max="Wide" + value_min="-1.3" + value_max="1.2" + camera_elevation=".1" + camera_distance=".3" + camera_angle="-20"> + <param_morph /> + </param> + + <param + id="28" + group="1" + name="Lips_Fat" + wearable="shape" + edit_group="driven" + value_min="0" + value_max="2"> + <param_morph /> + </param> + + <param + id="29" + group="1" + name="Wide_Upper_Lip" + wearable="shape" + edit_group="driven" + value_min="-.7" + value_max="1.3"> + <param_morph /> + </param> + + <param + id="30" + group="1" + name="Wide_Lower_Lip" + wearable="shape" + edit_group="driven" + value_min="-.7" + value_max="1.3"> + <param_morph /> + </param> + + <!--Arced eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1--> + <param + id="872" + group="1" + name="Arced_Eyebrows" + label="Eyebrow Arc" + wearable="hair" + edit_group="hair_eyebrows" + edit_group_order="3" + label_min="Flat" + label_max="Arced" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <!--Lower eyebrows became a driver/driven param with new min value for backwards compatibility between 1.0 and 1.1--> + <param + id="871" + group="1" + name="Lower_Eyebrows" + label="Eyebrow Height" + show_simple="true" + wearable="hair" + edit_group="hair_eyebrows" + edit_group_order="2.5" + label_min="Higher" + label_max="Lower" + value_min="-2" + value_max="2"> + <param_morph /> + </param> + + <param + id="35" + group="0" + name="Big_Ears" + label="Ear Size" + wearable="shape" + edit_group="shape_ears" + edit_group_order="1" + label_min="Small" + label_max="Large" + value_min="-1" + value_max="2" + camera_elevation=".1" + camera_distance=".3" + camera_angle="45"> + <param_morph /> + </param> + + <param + id="796" + group="0" + name="Pointy_Ears" + label="Ear Tips" + wearable="shape" + edit_group="shape_ears" + edit_group_order="4" + label_min="Flat" + label_max="Pointy" + value_min="-.4" + value_max="3" + camera_elevation=".1" + camera_distance=".3" + camera_angle="45"> + <param_morph /> + </param> + + <param + id="185" + group="0" + name="Deep_Chin" + label="Chin Depth" + wearable="shape" + edit_group="shape_chin" + edit_group_order="3" + label_min="Shallow" + label_max="Deep" + value_min="-1" + value_max="1" + camera_elevation=".1" + camera_distance=".4" + camera_angle="30"> + <param_morph /> + </param> + + <param + id="186" + group="1" + name="Egg_Head" + label="Egg Head" + wearable="shape" + edit_group="shape_head" + label_min="Chin Heavy" + label_max="Forehead Heavy" + value_min="-1.3" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> + + <param + id="187" + group="1" + name="Squash_Stretch_Head" + label="Squash/Stretch Head" + wearable="shape" + edit_group="shape_head" + label_min="Squash Head" + label_max="Stretch Head" + value_min="-.5" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph> + <volume_morph + name="HEAD" + scale="-0.008 -0.006 0.015"/> + </param_morph> + </param> + + <param + id="188" + group="1" + name="Square_Head" + wearable="shape" + label_min="Less Square" + label_max="More Square" + value_min="0" + value_max=".7" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> + + <param + id="189" + group="1" + wearable="shape" + name="Round_Head" + label_min="Less Round" + label_max="More Round" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> + + <param + id="194" + group="1" + name="Eye_Spread" + wearable="shape" + edit_group="shape_eyes" + label_min="Eyes Together" + label_max="Eyes Spread" + value_min="-2" + value_max="2"> + <param_morph /> + </param> + + <param + id="400" + sex="male" + group="1" + name="Displace_Hair_Facial" + label="Hair Thickess" + wearable="hair" + edit_group="hair_facial" + label_min="Cropped Hair" + label_max="Bushy Hair" + value_min="0" + value_max="2"> + <param_morph /> + </param> + + <param + id="506" + group="0" + name="Mouth_Height" + wearable="shape" + label="Mouth Position" + show_simple="true" + edit_group="shape_mouth" + edit_group_order="4" + label_min="High" + label_max="Low" + value_min="-2" + value_max="2" + camera_distance=".3" + camera_elevation=".04"> + <param_morph /> + </param> + + <param + id="633" + group="1" + name="Fat_Head" + label="Fat Head" + wearable="shape" + edit_group="shape_body" + label_min="Skinny" + label_max="Fat" + value_min="0" + value_max="1" + camera_elevation=".3"> + <param_morph/> + </param> + + <param + id="630" + group="1" + name="Forehead_Round" + label="Round Forehead" + wearable="shape" + label_min="Less" + label_max="More" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="631" + group="1" + name="Forehead_Slant" + label="Slanted Forehead" + wearable="shape" + label_min="Less" + label_max="More" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="650" + group="0" + name="Eyelid_Corner_Up" + label="Outer Eye Corner" + wearable="shape" + edit_group="shape_eyes" + edit_group_order="4" + label_min="Corner Down" + label_max="Corner Up" + value_min="-1.3" + value_max="1.2" + camera_elevation=".1" + camera_distance=".30"> + <param_morph /> + </param> + + <param + id="880" group="0" - name="Neck Length" + name="Eyelid_Inner_Corner_Up" + label="Inner Eye Corner" wearable="shape" - edit_group="shape_torso" - edit_group_order="3" - label_min="Short Neck" - label_max="Long Neck" - value_min="-1" - value_max="1" - value_default="0" - camera_elevation=".3" - camera_distance=".8" - camera_angle="15"> - <param_skeleton> - <bone - name="mNeck" - scale="0 0 .5" /> - </param_skeleton> - </param> - </skeleton> - - <mesh - type="hairMesh" - lod="0" - file_name="avatar_hair.llm" - min_pixel_width="320"> -<!-- begin morph targets --> - <param - id="180" - group="1" - name="Hair_Volume" - label="Hair Volume" - show_simple="true" - wearable="hair" - clothing_morph="true" - edit_group="hair_style" - label_min="Less" - label_max="More" - value_min="0" - value_max="1.3" + edit_group="shape_eyes" + edit_group_order="4.2" + label_min="Corner Down" + label_max="Corner Up" + value_min="-1.3" + value_max="1.2" camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + camera_distance=".30"> + <param_morph /> + </param> + - <param - id="761" - group="1" - name="Hair_Volume_Small" - label="Hair Volume" - show_simple="true" - wearable="hair" - edit_group="hair_style" - label_min="Less" - label_max="More" - value_min="0" - value_max="1.3" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + <param + id="653" + group="0" + name="Tall_Lips" + wearable="shape" + label="Lip Fullness" + show_simple="true" + edit_group="shape_mouth" + edit_group_order="2" + label_min="Less Full" + label_max="More Full" + value_min="-1" + value_max="2" + camera_distance=".3" + camera_elevation=".04"> + <param_morph /> + </param> - <param - id="181" - group="0" - name="Hair_Big_Front" - label="Big Hair Front" - wearable="hair" - edit_group="hair_style" - edit_group_order="5" - label_min="Less" - label_max="More" - value_min="-1" - value_max="1" - value_default="0.14" - camera_elevation=".1" - camera_distance=".5" - camera_angle="90"> - <param_morph /> - </param> + <param + id="656" + group="0" + name="Crooked_Nose" + wearable="shape" + label="Crooked Nose" + edit_group="shape_nose" + edit_group_order="9" + label_min="Nose Left" + label_max="Nose Right" + value_min="-2" + value_max="2" + camera_distance=".3" + camera_elevation=".04" + camera_angle="-20"> + <param_morph /> + </param> - <param - id="182" - group="0" - name="Hair_Big_Top" - label="Big Hair Top" - wearable="hair" - edit_group="hair_style" - edit_group_order="6" - label_min="Less" - label_max="More" - value_min="-1" - value_max="1" - value_default=".7" - camera_elevation=".1" - camera_distance=".5" - camera_angle="90"> - <param_morph /> - </param> + <param + id="657" + group="1" + name="Smile_Mouth" + wearable="shape" + label="Mouth Corner" + edit_group="shape_mouth" + label_min="Corner Normal" + label_max="Corner Up" + value_min="0" + value_max="1.4" + camera_distance=".3" + camera_elevation=".04"> + <param_morph /> + </param> - <param - id="183" - group="0" - name="Hair_Big_Back" - clothing_morph="true" - label="Big Hair Back" - wearable="hair" - edit_group="hair_style" - edit_group_order="7" - label_min="Less" - label_max="More" - value_min="-1" - value_max="1" - value_default="0.05" - camera_elevation=".1" - camera_distance=".7" - camera_angle="90"> - <param_morph /> - </param> + <param + id="658" + group="1" + name="Frown_Mouth" + wearable="shape" + label="Mouth Corner" + edit_group="shape_mouth" + label_min="Corner Normal" + label_max="Corner Down" + value_min="0" + value_max="1.2" + camera_distance=".3" + camera_elevation=".04"> + <param_morph /> + </param> - <param - id="184" - group="0" - name="Hair_Spiked" - label="Spiked Hair" - show_simple="true" - wearable="hair" - clothing_morph="true" - edit_group="hair_style" - edit_group_order="15" - label_min="No Spikes" - label_max="Big Spikes" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + <param + id="797" + group="1" + name="Fat_Upper_Lip" + wearable="shape" + label="Fat Upper Lip" + edit_group="shape_mouth" + label_min="Normal Upper" + label_max="Fat Upper" + value_min="0" + value_max="1.5" + camera_distance=".3" + camera_elevation=".04"> + <param_morph /> + </param> - <param - id="140" - group="0" - name="Hair_Part_Middle" - label="Middle Part" - wearable="hair" - edit_group="hair_style" - edit_group_order="17" - label_min="No Part" - label_max="Part" - value_min="0" - value_max="2" - camera_elevation=".1" - camera_distance=".5" - camera_angle="0"> - <param_morph /> - </param> + <param + id="798" + group="1" + name="Fat_Lower_Lip" + wearable="shape" + label="Fat Lower Lip" + edit_group="shape_mouth" + label_min="Normal Lower" + label_max="Fat Lower" + value_min="0" + value_max="1.5" + camera_distance=".3" + camera_elevation=".04"> + <param_morph /> + </param> - <param - id="141" - group="0" - name="Hair_Part_Right" - label="Right Part" - wearable="hair" - edit_group="hair_style" - edit_group_order="18" - label_min="No Part" - label_max="Part" - value_min="0" - value_max="2" - camera_elevation=".1" - camera_distance=".5" - camera_angle="0"> - <param_morph /> - </param> + <param + id="660" + group="1" + name="Shear_Head" + wearable="shape" + label="Shear Face" + edit_group="shape_head" + label_min="Shear Left" + label_max="Shear Right" + value_min="-2" + value_max="2" + value_default="0" + camera_distance=".5" + camera_elevation=".04"> + <param_morph /> + </param> - <param - id="142" - group="0" - name="Hair_Part_Left" - label="Left Part" - wearable="hair" - edit_group="hair_style" - edit_group_order="19" - label_min="No Part" - label_max="Part" - value_min="0" - value_max="2" - camera_elevation=".1" - camera_distance=".5" - camera_angle="0"> - <param_morph /> - </param> + <param + id="770" + group="1" + name="Elongate_Head" + wearable="shape" + label="Shear Face" + edit_group="shape_head" + label_min="Flat Head" + label_max="Long Head" + value_min="-1" + value_max="1" + value_default="0" + camera_distance=".5" + camera_elevation=".04"> + <param_morph> + <volume_morph + name="HEAD" + scale="0.02 0.0 0.0"/> + </param_morph> + </param> - <param - id="143" - group="0" - name="Hair_Sides_Full" - label="Full Hair Sides" - show_simple="true" - wearable="hair" - edit_group="hair_style" - edit_group_order="11" - label_min="Mowhawk" - label_max="Full Sides" - value_min="-4" - value_max="1.5" - value_default="0.125" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + <param + id="663" + group="0" + name="Shift_Mouth" + wearable="shape" + label="Shift Mouth" + edit_group="shape_mouth" + edit_group_order="7" + label_min="Shift Left" + label_max="Shift Right" + value_min="-2" + value_max="2" + value_default="0" + camera_distance=".35" + camera_elevation=".04" + camera_angle="-20"> + <param_morph /> + </param> - <param - id="144" - group="1" - name="Bangs_Front_Up" - label="Front Bangs Up" - wearable="hair" - edit_group="hair_style" - label_min="Bangs" - label_max="Bangs Up" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + <param + id="664" + group="0" + name="Pop_Eye" + wearable="shape" + label="Eye Pop" + edit_group="shape_eyes" + edit_group_order="8" + label_min="Pop Right Eye" + label_max="Pop Left Eye" + value_min="-1.3" + value_max="1.3" + value_default="0" + camera_elevation=".1" + camera_distance=".35"> + <param_morph /> + </param> - <param - id="145" - group="1" - clothing_morph="true" - name="Bangs_Front_Down" - label="Front Bangs Down" - wearable="hair" - edit_group="hair_style" - label_min="Bangs" - label_max="Bangs Down" - value_min="0" - value_max="5" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + <param + id="760" + group="0" + name="Jaw_Angle" + wearable="shape" + label="Jaw Angle" + edit_group="shape_chin" + edit_group_order="3.5" + label_min="Low Jaw" + label_max="High Jaw" + value_min="-1.2" + value_max="2" + value_default="0" + camera_distance=".5" + camera_elevation=".04" + camera_angle="70"> + <param_morph /> + </param> - <param - id="146" - group="1" - name="Bangs_Sides_Up" - label="Side Bangs Up" - wearable="hair" - edit_group="hair_style" - label_min="Side Bangs" - label_max="Side Bangs Up" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + <param + id="665" + group="0" + name="Jaw_Jut" + wearable="shape" + label="Jaw Jut" + edit_group="shape_chin" + edit_group_order="4" + label_min="Overbite" + label_max="Underbite" + value_min="-2" + value_max="2" + value_default="0" + camera_distance=".5" + camera_elevation=".04" + camera_angle="70"> + <param_morph /> + </param> - <param - id="147" - group="1" - clothing_morph="true" - name="Bangs_Sides_Down" - label="Side Bangs Down" - wearable="hair" - edit_group="hair_style" - label_min="Side Bangs" - label_max="Side Bangs Down" - value_min="0" - value_max="2" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + <param + id="686" + group="1" + name="Head_Eyes_Big" + wearable="shape" + label="Eye Size" + edit_group="shape_eyes" + label_min="Beady Eyes" + label_max="Anime Eyes" + show_simple="true" + value_min="-2" + value_max="2" + value_default="0"> + <param_morph /> + </param> - <param - id="148" - group="1" - name="Bangs_Back_Up" - label="Back Bangs Up" - wearable="hair" - edit_group="hair_style" - label_min="Back Bangs" - label_max="Back Bangs Up" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="150"> - <param_morph /> - </param> + <param + id="767" + group="1" + name="Bug_Eyed_Head" + wearable="shape" + label="Eye Depth" + edit_group="shape_eyes" + edit_group_order="4.5" + label_min="Sunken Eyes" + label_max="Bug Eyes" + value_min="-2" + value_max="2" + value_default="0"> + <param_morph /> + </param> + + <!-- + #Fat_Lips = Fat_Lips 34 1 0 1 + #Wide_Lips = Wide_Lips 35 1 0 1 + #Wide_Nose = Wide_Nose 36 1 0 1 + --> + <!-- + ############## + # Facial Expression morphs + ############## + --> + <param + id="300" + group="1" + name="Express_Closed_Mouth" + value_default="1" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="149" - group="1" - name="Bangs_Back_Down" - label="Back Bangs Down" - clothing_morph="true" - wearable="hair" - edit_group="hair_style" - label_min="Back Bangs" - label_max="Back Bangs Down" - value_min="0" - value_max="2" - camera_elevation=".1" - camera_distance=".5" - camera_angle="150"> - <param_morph /> - </param> + <param + id="301" + group="1" + name="Express_Tongue_Out" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="171" - group="1" - name="Hair_Front_Down" - label="Front Hair Down" - wearable="hair" - edit_group="hair_style" - label_min="Front Hair" - label_max="Front Hair Down" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + <param + id="302" + group="1" + name="Express_Surprise_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="172" - group="1" - name="Hair_Front_Up" - label="Front Hair Up" - wearable="hair" - edit_group="hair_style" - label_min="Front Hair" - label_max="Front Hair Up" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + <param + id="303" + group="1" + name="Express_Wink_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="173" - group="1" - name="Hair_Sides_Down" - label="Sides Hair Down" - wearable="hair" - edit_group="hair_style" - label_min="Sides Hair" - label_max="Sides Hair Down" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + <param + id="304" + group="1" + name="Express_Embarrassed_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="174" - group="1" - name="Hair_Sides_Up" - label="Sides Hair Up" - wearable="hair" - edit_group="hair_style" - label_min="Sides Hair" - label_max="Sides Hair Up" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + <param + id="305" + group="1" + name="Express_Shrug_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="175" - group="1" - name="Hair_Back_Down" - label="Back Hair Down" - clothing_morph="true" - wearable="hair" - edit_group="hair_style" - label_min="Back Hair" - label_max="Back Hair Down" - value_min="0" - value_max="3" - camera_elevation=".1" - camera_distance=".5" - camera_angle="150"> - <param_morph /> - </param> + <param + id="306" + group="1" + name="Express_Kiss" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="176" - group="1" - name="Hair_Back_Up" - label="Back Hair Up" - wearable="hair" - edit_group="hair_style" - label_min="Back Hair" - label_max="Back Hair Up" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="150"> - <param_morph /> - </param> + <param + id="307" + group="1" + name="Express_Bored_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="177" - group="0" - name="Hair_Rumpled" - label="Rumpled Hair" - show_simple="true" - wearable="hair" - clothing_morph="true" - edit_group="hair_style" - edit_group_order="14.5" - label_min="Smooth Hair" - label_max="Rumpled Hair" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + <param + id="308" + group="1" + name="Express_Repulsed_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="178" - group="1" - name="Hair_Swept_Back" - label="Swept Back Hair" - wearable="hair" - edit_group="hair_style" - label_min="NotHair" - label_max="Swept Back" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="90"> - <param_morph /> - </param> + <param + id="309" + group="1" + name="Express_Disdain" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="179" - group="1" - name="Hair_Swept_Forward" - label="Swept Forward Hair" - wearable="hair" - edit_group="hair_style" - label_min="Hair" - label_max="Swept Forward" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="90"> - <param_morph /> - </param> + <param + id="310" + group="1" + name="Express_Afraid_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="190" - group="1" - name="Hair_Tilt_Right" - label="Hair Tilted Right" - wearable="hair" - edit_group="hair_style" - label_min="Hair" - label_max="Tilt Right" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="0"> - <param_morph /> - </param> + <param + id="311" + group="1" + name="Express_Worry_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="191" - group="1" - name="Hair_Tilt_Left" - label="Hair Tilted Left" - wearable="hair" - edit_group="hair_style" - label_min="Hair" - label_max="Tilt Left" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="0"> - <param_morph /> - </param> + <param + id="312" + group="1" + name="Express_Cry_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="192" - group="0" - name="Bangs_Part_Middle" - label="Part Bangs" - wearable="hair" - edit_group="hair_style" - edit_group_order="20" - label_min="No Part" - label_max="Part Bangs" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="0"> - <param_morph /> - </param> + <param + id="313" + group="1" + name="Express_Sad_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="640" - group="1" - name="Hair_Egg_Head" - wearable="hair" - edit_group="hair_style" - value_min="-1.3" - value_max="1"> - <param_morph /> - </param> + <param + id="314" + group="1" + name="Express_Anger_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="641" - group="1" - name="Hair_Squash_Stretch_Head" - wearable="hair" - edit_group="hair_style" - value_min="-.5" - value_max="1"> - <param_morph /> - </param> + <param + id="315" + group="1" + name="Express_Frown" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="642" - group="1" - name="Hair_Square_Head" - wearable="hair" - edit_group="hair_style" - value_min="0" - value_max="1"> - <param_morph /> - </param> + <param + id="316" + group="1" + name="Express_Laugh_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> - <param - id="643" - group="1" - name="Hair_Round_Head" - wearable="hair" - edit_group="hair_style" - value_min="0" - value_max="1"> - <param_morph /> - </param> + <param + id="317" + group="1" + name="Express_Toothsmile" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="318" + group="1" + name="Express_Smile" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="632" + group="1" + name="Express_Open_Mouth" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <!-- + ############## + # Lipsync morphs + ############## + --> + + <param + id="70" + group="1" + name="Lipsync_Aah" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="71" + group="1" + name="Lipsync_Ooh" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <!-- + ############## + # other morphs (not user controlled) + ############## + --> + <param + id="40" + group="1" + name="Male_Head" + wearable="shape" + edit_group="driven" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="41" + group="1" + name="Old" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <!-- + ############## + # animatable morphs + ############## + --> + <param + id="51" + group="1" + name="Furrowed_Eyebrows" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="53" + group="1" + name="Surprised_Eyebrows" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="54" + group="1" + name="Worried_Eyebrows" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="55" + group="1" + name="Frown_Mouth" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="57" + group="1" + name="Smile_Mouth" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="58" + group="1" + name="Blink_Left" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="59" + group="1" + name="Blink_Right" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <!-- + #end morph targets + --> + </mesh> + + <mesh + type="headMesh" + lod="1" + file_name="avatar_head_1.llm" + min_pixel_width="160" + reference="avatar_head.llm"> + </mesh> + + <mesh + type="headMesh" + lod="2" + file_name="avatar_head_2.llm" + min_pixel_width="80" + reference="avatar_head.llm"> + </mesh> + + <mesh + type="headMesh" + lod="3" + file_name="avatar_head_3.llm" + min_pixel_width="40" + reference="avatar_head.llm"> + </mesh> + + <mesh + type="headMesh" + lod="4" + file_name="avatar_head_4.llm" + min_pixel_width="0" + reference="avatar_head.llm"> + </mesh> + + <mesh + type="eyelashMesh" + lod="0" + file_name="avatar_eyelashes.llm" + min_pixel_width="320"> + <param + shared="1" + id="660" + group="1" + name="Shear_Head" + wearable="shape" + label="Shear Face" + edit_group="shape_head" + label_min="Shear Left" + label_max="Shear Right" + value_min="-2" + value_max="2" + value_default="0" + camera_distance=".5" + camera_elevation=".04"> + <param_morph /> + </param> + + <param + shared="1" + id="770" + group="1" + name="Elongate_Head" + wearable="shape" + label="Shear Face" + edit_group="shape_head" + label_min="Flat Head" + label_max="Long Head" + value_min="-1" + value_max="1" + value_default="0" + camera_distance=".5" + camera_elevation=".04"> + <param_morph /> + </param> + + <param + shared="1" + id="664" + group="0" + name="Pop_Eye" + wearable="shape" + label="Eye Pop" + edit_group="shape_eyes" + edit_group_order="8" + label_min="Pop Right Eye" + label_max="Pop Left Eye" + value_min="-2" + value_max="2" + value_default="0" + camera_distance=".5" + camera_elevation=".04" + camera_angle="-20"> + <param_morph /> + </param> + + <param + shared="1" + id="21" + group="0" + name="Upper_Eyelid_Fold" + label="Upper Eyelid Fold" + wearable="shape" + edit_group="shape_eyes" + label_min="Uncreased" + label_max="Creased" + value_min="-0.2" + value_max="1.3" + camera_elevation=".1" + camera_distance=".35"> + <param_morph /> + </param> + + <param + shared="1" + id="24" + group="0" + name="Wide_Eyes" + label="Eye Opening" + wearable="shape" + edit_group="shape_eyes" + label_min="Narrow" + label_max="Wide" + show_simple="true" + value_min="-1.5" + value_max="2" + camera_elevation=".1" + camera_distance=".3"> + <param_morph /> + </param> + + <param + shared="1" + id="186" + group="1" + name="Egg_Head" + label="Egg Head" + wearable="shape" + edit_group="shape_head" + label_min="Chin Heavy" + label_max="Forehead Heavy" + value_min="-1.3" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> + + <param + shared="1" + id="187" + group="1" + name="Squash_Stretch_Head" + label="Squash/Stretch Head" + wearable="shape" + edit_group="shape_head" + label_min="Squash Head" + label_max="Stretch Head" + value_min="-.5" + value_max="1" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_morph /> + </param> + + <param + shared="1" + id="194" + group="1" + name="Eye_Spread" + edit_group="shape_eyes" + label_min="Eyes Together" + label_max="Eyes Spread" + value_min="-2" + value_max="2"> + <param_morph /> + </param> + + <param + id="518" + group="0" + name="Eyelashes_Long" + wearable="shape" + label="Eyelash Length" + edit_group="shape_eyes" + edit_group_order="7" + label_min="Short" + label_max="Long" + value_min="-.3" + value_max="1.5" + camera_elevation=".1" + camera_distance=".30" + camera_angle="-20"> + <param_morph /> + </param> + + <param + shared="1" + id="650" + group="0" + name="Eyelid_Corner_Up" + label="Outer Eye Corner" + wearable="shape" + edit_group="shape_eyes" + label_min="Corner Down" + label_max="Corner Up" + value_min="-1.3" + value_max="1.2" + camera_elevation=".1" + camera_distance=".3"> + <param_morph /> + </param> + + + <param + shared="1" + id="880" + group="0" + name="Eyelid_Inner_Corner_Up" + label="Inner Eye Corner" + wearable="shape" + edit_group="shape_eyes" + label_min="Corner Down" + label_max="Corner Up" + value_min="-1.3" + value_max="1.2" + camera_elevation=".1" + camera_distance=".3"> + <param_morph /> + </param> + + <param + shared="1" + id="686" + group="1" + name="Head_Eyes_Big" + wearable="shape" + label="Eye Size" + edit_group="shape_eyes" + label_min="Beady Eyes" + label_max="Anime Eyes" + value_min="-2" + value_max="2" + show_simple="true" + value_default="0"> + <param_morph /> + </param> + + <param + shared="1" + id="767" + group="1" + name="Bug_Eyed_Head" + wearable="shape" + label="Eye Depth" + edit_group="shape_eyes" + edit_group_order="4.5" + label_min="Sunken Eyes" + label_max="Bug Eyes" + value_min="-2" + value_max="2" + value_default="0"> + <param_morph /> + </param> + + <!-- + ############## + # Facial Expression morphs + ############## + --> + <param + shared="1" + id="301" + group="1" + name="Express_Tongue_Out" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + shared="1" + id="302" + group="1" + name="Express_Surprise_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + shared="1" + id="303" + group="1" + name="Express_Wink_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + shared="1" + id="304" + group="1" + name="Express_Embarrassed_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + shared="1" + id="305" + group="1" + name="Express_Shrug_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + shared="1" + id="306" + group="1" + name="Express_Kiss" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + shared="1" + id="307" + group="1" + name="Express_Bored_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + shared="1" + id="308" + group="1" + name="Express_Repulsed_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + shared="1" + id="309" + group="1" + name="Express_Disdain" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + shared="1" + id="310" + group="1" + name="Express_Afraid_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + shared="1" + id="312" + group="1" + name="Express_Cry_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + shared="1" + id="313" + group="1" + name="Express_Sad_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + shared="1" + id="314" + group="1" + name="Express_Anger_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + shared="1" + id="315" + group="1" + name="Express_Frown" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + shared="1" + id="316" + group="1" + name="Express_Laugh_Emote" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + shared="1" + id="317" + group="1" + name="Express_Toothsmile" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + shared="1" + id="318" + group="1" + name="Express_Smile" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <!-- + ############## + # other morphs (not user controlled) + ############## + --> + <param + shared="1" + id="41" + group="1" + name="Old" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <!-- + ############## + # animatable morphs + ############## + --> + <param + shared="1" + id="58" + group="1" + name="Blink_Left" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + shared="1" + id="59" + group="1" + name="Blink_Right" + value_min="0" + value_max="1"> + <param_morph /> + </param> + </mesh> + + <!-- + #headMesh2 = + #headMesh3 = + --> + <mesh + type="upperBodyMesh" + lod="0" + file_name="avatar_upper_body.llm" + min_pixel_width="320"> + <!-- + #begin morph targets + ############# + # tweakable morphs + ############# + --> + <param + id="104" + group="1" + name="Big_Belly_Torso" + wearable="shape" + edit_group="driven" + value_min="0" + value_max="1"> + <param_morph> + <volume_morph + name="BELLY" + scale="0.075 0.04 0.03" + pos="0.07 0 -0.07"/> + </param_morph> + </param> + + <param + id="626" + sex="female" + group="1" + name="Big_Chest" + label="Chest Size" + wearable="shape" + edit_group="shape_torso" + label_min="Small" + label_max="Large" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance="1" + camera_angle="15"> + <param_morph /> + </param> + + <param + id="627" + sex="female" + group="1" + name="Small_Chest" + label="Chest Size" + wearable="shape" + edit_group="shape_torso" + label_min="Large" + label_max="Small" + value_min="0" + value_max="1" + camera_elevation="0" + camera_distance=".28"> + <param_morph /> + </param> + + <param + id="843" + sex="female" + group="1" + name="No_Chest" + label="Chest Size" + wearable="shape" + edit_group="shape_torso" + label_min="Some" + label_max="None" + value_min="0" + value_max="1" + camera_elevation="0" + camera_distance=".28"> + <param_morph /> + </param> + + <param + id="106" + group="1" + name="Muscular_Torso" + label="Torso Muscles" + show_simple="true" + wearable="shape" + edit_group="shape_torso" + label_min="Regular" + label_max="Muscular" + value_min="0" + value_max="1.4" + camera_elevation=".3" + camera_distance="1.2"> + <param_morph> + <volume_morph + name="L_CLAVICLE" + scale="0.02 0.0 0.005" + pos="0.0 0 0.005"/> + <volume_morph + name="L_UPPER_ARM" + scale="0.015 0.0 0.005" + pos="0.015 0 0"/> + <volume_morph + name="L_LOWER_ARM" + scale="0.005 0.0 0.005" + pos="0.005 0 0"/> + <volume_morph + name="R_CLAVICLE" + scale="0.02 0.0 0.005" + pos="0.0 0 0.005"/> + <volume_morph + name="R_UPPER_ARM" + scale="0.015 0.0 0.005" + pos="0.015 0 0"/> + <volume_morph + name="R_LOWER_ARM" + scale="0.005 0.0 0.005" + pos="0.005 0 0"/> + </param_morph> + </param> + + <param + id="648" + group="1" + sex="female" + name="Scrawny_Torso" + label="Torso Muscles" + show_simple="true" + wearable="shape" + edit_group="shape_torso" + label_min="Regular" + label_max="Scrawny" + value_min="0" + value_max="1.3" + camera_elevation=".3" + camera_distance="1.2"> + <param_morph> + <volume_morph + name="BELLY" + scale="0.0 -0.01 0.0" + pos="0.0 0.0 0"/> + <volume_morph + name="CHEST" + scale="-0.01 -0.01 0.0" + pos="0.01 0.0 0"/> + <volume_morph + name="L_CLAVICLE" + scale="0.0 -0.03 -0.005" + pos="0.0 0 -0.005"/> + <volume_morph + name="L_UPPER_ARM" + scale="-0.01 -0.01 -0.02" + pos="0 0 0"/> + <volume_morph + name="L_LOWER_ARM" + scale="-0.005 0.0 -0.01" + pos="-0.005 0 0"/> + <volume_morph + name="R_CLAVICLE" + scale="0.0 -0.03 -0.005" + pos="0.0 0 -0.005"/> + <volume_morph + name="R_UPPER_ARM" + scale="-0.01 -0.01 -0.02" + pos="0 0 0"/> + <volume_morph + name="R_LOWER_ARM" + scale="-0.005 0.0 -0.01" + pos="-0.005 0 0"/> + </param_morph> + </param> + + <param + id="677" + group="1" + sex="male" + name="Scrawny_Torso_Male" + label="Torso Scrawny" + wearable="shape" + edit_group="shape_torso" + label_min="Regular" + label_max="Scrawny" + value_min="0" + value_max="1.3" + camera_elevation=".3" + camera_distance="1.2"> + <param_morph> + <volume_morph + name="BELLY" + scale="-0.01 -0.01 0.0" + pos="0.01 0.0 0"/> + <volume_morph + name="CHEST" + scale="-0.02 -0.02 0.0" + pos="0.01 0.0 0"/> + <volume_morph + name="L_CLAVICLE" + scale="0.0 -0.03 -0.005" + pos="0.0 0 -0.005"/> + <volume_morph + name="L_UPPER_ARM" + scale="-0.01 -0.01 -0.02" + pos="0 0 0"/> + <volume_morph + name="L_LOWER_ARM" + scale="-0.005 0.0 -0.01" + pos="-0.005 0 0"/> + <volume_morph + name="R_CLAVICLE" + scale="0.0 -0.03 -0.005" + pos="0.0 0 -0.005"/> + <volume_morph + name="R_UPPER_ARM" + scale="-0.01 -0.01 -0.02" + pos="0 0 0"/> + <volume_morph + name="R_LOWER_ARM" + scale="-0.005 0.0 -0.01" + pos="-0.005 0 0"/> + </param_morph> + </param> + + <param + id="634" + group="1" + name="Fat_Torso" + label="Fat Torso" + wearable="shape" + edit_group="shape_body" + label_min="skinny" + label_max="fat" + value_min="0" + value_max="1" + camera_elevation=".3"> + <param_morph> + <volume_morph + name="CHEST" + scale="0.02 0.03 0.03" + pos="0 0 -0.03"/> + <volume_morph + name="BELLY" + scale="0.09 0.08 0.07" + pos="0 0 -0.05"/> + <volume_morph + name="L_CLAVICLE" + scale="0.0 0.0 0.015"/> + <volume_morph + name="L_UPPER_ARM" + scale="0.02 0.0 0.02" + pos="0.0 0.0 -0.02"/> + <volume_morph + name="L_LOWER_ARM" + scale="0.01 0.0 0.01" + pos="0.0 0.0 -0.01"/> + <volume_morph + name="R_CLAVICLE" + scale="0.0 0.0 0.015"/> + <volume_morph + name="R_UPPER_ARM" + scale="0.02 0.0 0.02" + pos="0.0 0.0 -0.02"/> + <volume_morph + name="R_LOWER_ARM" + scale="0.01 0.0 0.01" + pos="0.0 0.0 -0.01"/> + <volume_morph + name="NECK" + scale="0.015 0.01 0.0"/> + <volume_morph + name="HEAD" + scale="0.0 0.0 0.01" + pos="0 0 -0.01"/> + </param_morph> + + </param> + + <param + id="507" + group="0" + sex="female" + name="Breast_Gravity" + label="Breast Buoyancy" + wearable="shape" + edit_group="shape_torso" + edit_group_order="7" + label_min="Less Gravity" + label_max="More Gravity" + value_default="0" + value_min="-1.5" + value_max="2" + camera_elevation=".3" + camera_distance=".8"> + <param_morph /> + </param> + + <param + id="628" + group="1" + name="Displace_Loose_Upperbody" + label="Shirt Fit" + wearable="shirt" + edit_group="driven" + clothing_morph="true" + value_min="0" + value_max="1" + value_default="0"> + <param_morph /> + </param> + + <param + id="840" + group="0" + name="Shirtsleeve_flair" + label="Sleeve Looseness" + show_simple="true" + wearable="shirt" + edit_group="shirt" + edit_group_order="6" + clothing_morph="true" + label_min="Tight Sleeves" + label_max="Loose Sleeves" + value_min="0" + value_max="1.5" + camera_distance="1.8" + camera_angle="30" + camera_elevation="-.3"> + <param_morph /> + </param> + + <param + id="855" + group="1" + name="Love_Handles" + wearable="shape" + edit_group="driven" + value_default="0" + value_min="-1" + value_max="2"> + <param_morph> + <volume_morph + name="BELLY" + scale="0.0 0.02 0.0"/> + </param_morph> + </param> + + <param + id="684" + group="0" + sex="female" + name="Breast_Female_Cleavage" + label="Breast Cleavage" + wearable="shape" + edit_group="shape_torso" + edit_group_order="8" + label_min="Separate" + label_max="Join" + value_default="0" + value_min="-.3" + value_max="1.3" + camera_elevation=".3" + camera_distance=".8"> + <param_morph /> + </param> + + <param + id="685" + group="0" + sex="male" + name="Chest_Male_No_Pecs" + label="Pectorals" + wearable="shape" + edit_group="shape_torso" + edit_group_order="5" + label_min="Big Pectorals" + label_max="Sunken Chest" + value_default="0" + value_min="-.5" + value_max="1.1" + camera_elevation=".3" + camera_distance="1.2"> + <param_morph /> + </param> + + <!-- ############# # + other morphs (not user controlled) + ############# --> + <param + id="100" + group="1" + name="Male_Torso" + wearable="shape" + edit_group="driven" + label_min="Male_Torso" + value_min="0" + value_max="1"> + <param_morph> + <volume_morph + name="CHEST" + scale="0.03 0.04 0.02" + pos="-0.03 0 -0.01"/> + <volume_morph + name="BELLY" + scale="0.03 0.03 0.0" + pos="-0.03 0 0.02"/> + <volume_morph + name="L_CLAVICLE" + scale="0.02 0.0 0.01" + pos="-0.02 0 0"/> + <volume_morph + name="L_UPPER_ARM" + scale="0.01 0.0 0.01" + pos="0.0 0.0 -0.01"/> + <volume_morph + name="L_LOWER_ARM" + scale="0.005 0.0 0.005" + pos="0.0 0.0 -0.005"/> + <volume_morph + name="R_CLAVICLE" + scale="0.02 0.0 0.01" + pos="-0.02 0 0"/> + <volume_morph + name="R_UPPER_ARM" + scale="0.01 0.0 0.01" + pos="0.0 0.0 -0.01"/> + <volume_morph + name="R_LOWER_ARM" + scale="0.005 0.0 0.005" + pos="0.0 0.0 -0.005"/> + <volume_morph + name="NECK" + scale="0.015 0.01 0.0"/> + <volume_morph + name="HEAD" + scale="0.0 0.0 0.01" + pos="0 0 -0.01"/> + </param_morph> + </param> + + <!-- + ############## + # animatable morphs + ############## + --> + <param + id="101" + group="1" + name="Hands_Relaxed" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="102" + group="1" + name="Hands_Point" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="103" + group="1" + name="Hands_Fist" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="666" + group="1" + name="Hands_Relaxed_L" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="667" + group="1" + name="Hands_Point_L" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="668" + group="1" + name="Hands_Fist_L" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="669" + group="1" + name="Hands_Relaxed_R" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="670" + group="1" + name="Hands_Point_R" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="671" + group="1" + name="Hands_Fist_R" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="672" + group="1" + name="Hands_Typing" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="766" + group="1" + name="Hands_Salute_R" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="791" + group="1" + name="Hands_Peace_R" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="792" + group="1" + name="Hands_Spread_R" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <!-- + #end morph targets + --> + </mesh> + + <mesh + type="upperBodyMesh" + lod="1" + file_name="avatar_upper_body_1.llm" + min_pixel_width="160" + reference="avatar_upper_body.llm"> + </mesh> + + <mesh + type="upperBodyMesh" + lod="2" + file_name="avatar_upper_body_2.llm" + min_pixel_width="80" + reference="avatar_upper_body.llm"> + </mesh> + + <mesh + type="upperBodyMesh" + lod="3" + file_name="avatar_upper_body_3.llm" + min_pixel_width="40" + reference="avatar_upper_body.llm"> + </mesh> + + <mesh + type="upperBodyMesh" + lod="4" + file_name="avatar_upper_body_4.llm" + min_pixel_width="0" + reference="avatar_upper_body.llm"> + </mesh> + + <!-- + #upperBodyMesh2 = + #upperBodyMesh3 = + --> + <mesh + type="lowerBodyMesh" + lod="0" + file_name="avatar_lower_body.llm" + min_pixel_width="320"> + <!-- + #begin morph targets + ############# + # tweakable morphs + ############# + --> + <param + id="156" + group="1" + name="Big_Belly_Legs" + wearable="shape" + edit_group="driven" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="151" + group="1" + name="Big_Butt_Legs" + label="Butt Size" + wearable="shape" + edit_group="shape_legs" + label_min="Regular" + label_max="Large" + value_min="0" + value_max="1"> + <param_morph> + <volume_morph + name="PELVIS" + scale="0.03 0.0 0.02" + pos="-0.03 0 -0.025"/> + </param_morph> + </param> + + <param + id="794" + group="1" + name="Small_Butt" + label="Butt Size" + wearable="shape" + edit_group="shape_legs" + label_min="Regular" + label_max="Small" + value_min="0" + value_max="1"> + <param_morph> + <volume_morph + name="PELVIS" + scale="-0.01 0.0 0.0" + pos="0.01 0 0.0"/> + </param_morph> + </param> + + <param + id="152" + group="1" + name="Muscular_Legs" + label="Leg Muscles" + show_simple="true" + wearable="shape" + edit_group="shape_legs" + label_min="Regular Muscles" + label_max="More Muscles" + value_min="0" + value_max="1.5" + camera_distance="1.3" + camera_elevation="-.5"> + <param_morph> + <volume_morph + name="L_UPPER_LEG" + scale="0.015 0.015 0.0" + pos="0.0 0 0.0"/> + <volume_morph + name="L_LOWER_LEG" + scale="0.01 0.01 0.0" + pos="0.0 0 0.0"/> + <volume_morph + name="R_UPPER_LEG" + scale="0.015 0.015 0.0" + pos="0.0 0 0.0"/> + <volume_morph + name="R_LOWER_LEG" + scale="0.01 0.01 0.0" + pos="0.0 0 0.0"/> + </param_morph> + </param> + + <param + id="651" + group="1" + name="Scrawny_Legs" + label="Scrawny Leg" + wearable="shape" + edit_group="shape_legs" + label_min="Regular Muscles" + label_max="Less Muscles" + value_min="0" + value_max="1.5" + camera_distance="1.3" + camera_elevation="-.5"> + <param_morph> + <volume_morph + name="L_UPPER_LEG" + scale="-0.03 -0.03 0.0" + pos="0.0 0 0.0"/> + <volume_morph + name="L_LOWER_LEG" + scale="-0.015 -0.015 0.0" + pos="0.0 0 0.0"/> + <volume_morph + name="R_UPPER_LEG" + scale="-0.03 -0.03 0.0" + pos="0.0 0 0.0"/> + <volume_morph + name="R_LOWER_LEG" + scale="-0.015 -0.015 0.0" + pos="0.0 0 0.0"/> + </param_morph> + </param> + + <param + id="853" + group="1" + name="Bowed_Legs" + label="Knee Angle" + wearable="shape" + value_min="-1" + value_max="1"> + <param_morph> + <volume_morph + name="L_UPPER_LEG" + pos="0.0 0.03 0.0"/> + <volume_morph + name="L_LOWER_LEG" + pos="0.0 0.03 0.0"/> + <volume_morph + name="R_UPPER_LEG" + pos="0.0 -0.03 0.0"/> + <volume_morph + name="R_LOWER_LEG" + pos="0.0 -0.03 0.0"/> + </param_morph> + </param> + + <param + id="500" + group="1" + name="Shoe_Heel_Height" + label="Heel Height" + wearable="shoes" + edit_group="shoes" + label_min="Low Heels" + label_max="High Heels" + value_min="0" + value_max="1" + camera_distance="1.5" + camera_elevation="-.5"> + <param_morph /> + </param> + + <param + id="501" + group="1" + name="Shoe_Platform_Height" + label="Platform Height" + wearable="shoes" + edit_group="shoes" + label_min="Low Platforms" + label_max="High Platforms" + value_min="0" + value_max="1" + camera_distance="1.5" + camera_elevation="-.5"> + <param_morph /> + </param> + + <param + id="508" + group="0" + name="Shoe_Platform_Width" + label="Platform Width" + wearable="shoes" + edit_group="shoes" + edit_group_order="7" + label_min="Narrow" + label_max="Wide" + value_min="-1" + value_max="2" + camera_angle="15" + camera_distance="1.5" + camera_elevation="-1"> + <param_morph /> + </param> + + <param + id="509" + group="1" + name="Shoe_Heel_Point" + label="Heel Shape" + wearable="shoes" + edit_group="shoes" + label_min="Default Heels" + label_max="Pointy Heels" + value_min="0" + value_max="1" + camera_distance="1.3" + camera_elevation="-.5"> + <param_morph /> + </param> + + <param + id="510" + group="1" + name="Shoe_Heel_Thick" + label="Heel Shape" + wearable="shoes" + edit_group="shoes" + label_min="default Heels" + label_max="Thick Heels" + value_min="0" + value_max="1" + camera_distance="1.3" + camera_elevation="-.5"> + <param_morph /> + </param> + + <param + id="511" + group="1" + name="Shoe_Toe_Point" + label="Toe Shape" + wearable="shoes" + edit_group="shoes" + label_min="Default Toe" + label_max="Pointy Toe" + value_min="0" + value_max="1" + camera_distance="1.3" + camera_elevation="-.5"> + <param_morph /> + </param> + + <param + id="512" + group="1" + name="Shoe_Toe_Square" + label="Toe Shape" + wearable="shoes" + edit_group="shoes" + label_min="Default Toe" + label_max="Square Toe" + value_min="0" + value_max="1" + camera_distance="1.5" + camera_elevation="-.5"> + <param_morph /> + </param> + + <param + id="654" + group="0" + name="Shoe_Toe_Thick" + label="Toe Thickness" + wearable="shoes" + edit_group="shoes" + edit_group_order="5" + label_min="Flat Toe" + label_max="Thick Toe" + value_min="0" + value_max="2" + camera_angle="15" + camera_distance="1.5" + camera_elevation="-1"> + <param_morph /> + </param> + + <param + id="515" + group="0" + name="Foot_Size" + label="Foot Size" + wearable="shape" + edit_group="shape_legs" + edit_group_order="6" + label_min="Small" + label_max="Big" + value_min="-1" + value_max="3" + camera_angle="45" + camera_distance="1.1" + camera_elevation="-1"> + <param_morph> + <volume_morph + name="L_FOOT" + scale="0.02 0.01 0.0" + pos="0.01 0 0"/> + <volume_morph + name="R_FOOT" + scale="0.02 0.01 0.0" + pos="0.01 0 0"/> + </param_morph> + </param> + + <param + id="516" + group="1" + name="Displace_Loose_Lowerbody" + label="Pants Fit" + wearable="pants" + edit_group="driven" + clothing_morph="true" + value_min="0" + value_max="1" + value_default="0"> + <param_morph /> + </param> + + <param + id="625" + group="0" + name="Leg_Pantflair" + label="Cuff Flare" + show_simple="true" + wearable="pants" + edit_group="pants" + edit_group_order="3" + clothing_morph="true" + label_min="Tight Cuffs" + label_max="Flared Cuffs" + value_min="0" + value_max="1.5" + camera_distance="1.8" + camera_angle="30" + camera_elevation="-.3"> + <param_morph /> + </param> + + <param + id="793" + group="1" + name="Leg_Longcuffs" + label="Longcuffs" + wearable="pants" + edit_group="driven" + clothing_morph="true" + value_min="0" + value_max="3" + value_default="0"> + <param_morph /> + </param> + + <param + id="638" + group="0" + name="Low_Crotch" + label="Pants Crotch" + wearable="pants" + clothing_morph="true" + edit_group="pants" + edit_group_order="4" + label_min="High and Tight" + label_max="Low and Loose" + value_min="0" + value_max="1.3" + camera_distance="1.2" + camera_angle="-20" + camera_elevation="-.3"> + <param_morph /> + </param> + + <param + id="635" + group="1" + name="Fat_Legs" + label="Fat Torso" + wearable="shape" + edit_group="shape_body" + label_min="skinny" + label_max="fat" + value_min="0" + value_max="1"> + <param_morph> + <volume_morph + name="PELVIS" + scale="0.03 0.06 0.0"/> + <volume_morph + name="R_UPPER_LEG" + scale="0.02 0.02 0.0" + pos="0.0 -0.02 0.0"/> + <volume_morph + name="R_LOWER_LEG" + scale="0.01 0.01 0.0"/> + <volume_morph + name="L_UPPER_LEG" + scale="0.02 0.02 0.0" + pos="0.0 0.02 0.0"/> + <volume_morph + name="L_LOWER_LEG" + scale="0.01 0.01 0.0"/> + </param_morph> + </param> + + <param + id="854" + group="1" + name="Saddlebags" + wearable="shape" + edit_grouo="driven" + value_min="-.5" + value_max="3"> + <param_morph> + <volume_morph + name="PELVIS" + scale="0.0 0.025 0.0"/> + </param_morph> + + </param> + + <param + id="879" + group="0" + sex="male" + name="Male_Package" + label="Package" + wearable="shape" + edit_group="shape_legs" + edit_group_order="4.6" + label_min="Coin Purse" + label_max="Duffle Bag" + value_default="0" + value_min="-.5" + value_max="2" + camera_angle="60" + camera_distance=".6"> + <param_morph /> + </param> + + <!-- + ############# + # other morphs (not user controlled) + ############# + --> + <param + id="153" + group="1" + name="Male_Legs" + wearable="shape" + edit_group="driven" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <!-- + #end morph targets + --> + </mesh> + + <mesh + type="lowerBodyMesh" + lod="1" + file_name="avatar_lower_body_1.llm" + min_pixel_width="160" + reference="avatar_lower_body.llm"> + </mesh> + + <mesh + type="lowerBodyMesh" + lod="2" + file_name="avatar_lower_body_2.llm" + min_pixel_width="80" + reference="avatar_lower_body.llm"> + </mesh> + + <mesh + type="lowerBodyMesh" + lod="3" + file_name="avatar_lower_body_3.llm" + min_pixel_width="40" + reference="avatar_lower_body.llm"> + </mesh> + + <mesh + type="lowerBodyMesh" + lod="4" + file_name="avatar_lower_body_4.llm" + min_pixel_width="0" + reference="avatar_lower_body.llm"> + </mesh> + + <!-- + #lowerBodyMesh2 = + #lowerBodyMesh3 = + --> + <!-- + #eyeLidLeftMesh = + --> + <mesh + type="eyeBallLeftMesh" + lod="0" + file_name="avatar_eye.llm" + min_pixel_width="320"> + <!-- begin morph_params --> + <param + id="679" + group="1" + name="Eyeball_Size" + label="Eyeball Size" + wearable="shape" + edit_group="shape_eyes" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".10"> + <param_morph /> + </param> + + <param + id="687" + group="1" + name="Eyeball_Size" + label="Big Eyeball" + wearable="shape" + edit_group="shape_eyes" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".25"> + <param_morph /> + </param> + </mesh> + + <mesh + type="eyeBallLeftMesh" + lod="1" + file_name="avatar_eye_1.llm" + min_pixel_width="80"> + <!-- begin morph_params --> + <param + id="694" + group="1" + name="Eyeball_Size" + label="Eyeball Size" + wearable="shape" + edit_group="shape_eyes" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".10"> + <param_morph /> + </param> + + <param + id="695" + group="1" + name="Eyeball_Size" + label="Big Eyeball" + wearable="shape" + edit_group="shape_eyes" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".25"> + <param_morph /> + </param> + </mesh> + + <!-- + #eyeLidRightMesh = + --> + <mesh + type="eyeBallRightMesh" + lod="0" + file_name="avatar_eye.llm" + min_pixel_width="320"> + <!-- begin morph_params --> + <param + id="680" + group="1" + name="Eyeball_Size" + label="Eyeball Size" + wearable="shape" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".10"> + <param_morph /> + </param> + + <param + id="688" + group="1" + name="Eyeball_Size" + label="Big Eyeball" + wearable="shape" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".25"> + <param_morph /> + </param> + </mesh> + + <mesh + type="eyeBallRightMesh" + lod="1" + file_name="avatar_eye_1.llm" + min_pixel_width="80"> + <!-- begin morph_params --> + <param + id="681" + group="1" + name="Eyeball_Size" + label="Eyeball Size" + wearable="shape" + edit_group="shape_eyes" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".10"> + <param_morph /> + </param> + + <param + id="691" + group="1" + name="Eyeball_Size" + label="Big Eyeball" + wearable="shape" + edit_group="shape_eyes" + label_min="small eye" + label_max="big eye" + value_min="-.25" + value_max=".25"> + <param_morph /> + </param> + </mesh> + + <mesh + type="skirtMesh" + lod="0" + file_name="avatar_skirt.llm" + min_pixel_width="320"> + <param + id="845" + group="1" + name="skirt_poofy" + label="poofy skirt" + clothing_morph="true" + wearable="skirt" + edit_group="skirt" + label_min="less poofy" + label_max="more poofy" + value_min="0" + value_max="1.5"> + <param_morph /> + </param> + + <param + id="846" + group="1" + name="skirt_loose" + label="loose skirt" + clothing_morph="true" + wearable="skirt" + edit_group="skirt" + label_min="form fitting" + label_max="loose" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="866" + group="1" + name="skirt_tight" + label="tight skirt" + clothing_morph="true" + wearable="skirt" + edit_group="skirt" + label_min="form fitting" + label_max="loose" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="867" + group="1" + name="skirt_smallbutt" + label="tight skirt" + clothing_morph="false" + wearable="skirt" + edit_group="skirt" + cross_wearable="true" + label_min="form fitting" + label_max="loose" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="848" + group="0" + name="skirt_bustle" + label="bustle skirt" + clothing_morph="true" + wearable="skirt" + edit_group_order="3" + edit_group="skirt" + label_min="no bustle" + label_max="more bustle" + value_min="0" + value_max="2" + value_default=".2" + camera_angle="100" + camera_distance="1.3" + camera_elevation="-.5"> + <param_morph /> + </param> + + <param + id="847" + group="1" + name="skirt_bowlegs" + label="legs skirt" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + value_min="-1" + value_max="1" + value_default="0"> + <param_morph /> + </param> + + <param + id="852" + group="1" + name="skirt_bigbutt" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + label="bigbutt skirt" + label_min="less" + label_max="more" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="849" + group="1" + name="skirt_belly" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + label="big belly skirt" + value_min="0" + value_max="1"> + <param_morph /> + </param> + + <param + id="850" + group="1" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + name="skirt_saddlebags" + value_min="-.5" + value_max="3"> + <param_morph /> + </param> + + <param + id="851" + group="1" + name="skirt_chubby" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + label_min="less" + label_max="more" + value_min="0" + value_max="1" + value_default="0"> + <param_morph /> + </param> + + <param + id="856" + group="1" + name="skirt_lovehandles" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + label_min="less" + label_max="more" + value_min="-1" + value_max="2" + value_default="0"> + <param_morph /> + </param> + + <!-- + ############# + # other morphs (not user controlled) + ############# + --> + <param + id="857" + group="1" + name="skirt_male" + wearable="skirt" + edit_group="driven" + cross_wearable="true" + value_min="0" + value_max="1"> + <param_morph /> + </param> + </mesh> + + <mesh + type="skirtMesh" + lod="1" + file_name="avatar_skirt_1.llm" + min_pixel_width="160" + reference="avatar_skirt.llm"> + </mesh> + + <mesh + type="skirtMesh" + lod="2" + file_name="avatar_skirt_2.llm" + min_pixel_width="80" + reference="avatar_skirt.llm"> + </mesh> + + <mesh + type="skirtMesh" + lod="3" + file_name="avatar_skirt_3.llm" + min_pixel_width="40" + reference="avatar_skirt.llm"> + </mesh> + + <mesh + type="skirtMesh" + lod="4" + file_name="avatar_skirt_4.llm" + min_pixel_width="0" + reference="avatar_skirt.llm"> + </mesh> + + <!-- =========================================================== --> + <global_color + name="skin_color"> + <param + id="111" + group="0" + wearable="skin" + edit_group="skin_color" + edit_group_order="1" + name="Pigment" + show_simple="true" + label_min="Light" + label_max="Dark" + value_min="0" + value_max="1" + value_default=".5"> + <param_color> + <value + color="252, 215, 200, 255" /> + + <value + color="240, 177, 112, 255" /> + + <value + color="90, 40, 16, 255" /> + + <value + color="29, 9, 6, 255" /> + </param_color> + </param> + + <param + id="110" + group="0" + wearable="skin" + edit_group="skin_color" + edit_group_order="2" + name="Red Skin" + label="Ruddiness" + label_min="Pale" + label_max="Ruddy" + value_min="0" + value_max="0.1"> + <param_color + operation="blend"> + <value + color="218, 41, 37, 255" /> + </param_color> + </param> + + <param + id="108" + group="0" + wearable="skin" + edit_group="skin_color" + edit_group_order="3" + name="Rainbow Color" + show_simple="true" + label_min="None" + label_max="Wild" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5"> + <param_color> + <value + color=" 0, 0, 0, 255" /> + + <value + color="255, 0, 255, 255" /> + + <value + color="255, 0, 0, 255" /> + + <value + color="255, 255, 0, 255" /> + + <value + color=" 0, 255, 0, 255" /> + + <value + color=" 0, 255, 255, 255" /> + + <value + color=" 0, 0, 255, 255" /> + + <value + color="255, 0, 255, 255" /> + </param_color> + </param> + </global_color> + + <!-- =========================================================== --> + <global_color + name="hair_color"> + <param + id="114" + group="0" + wearable="hair" + edit_group="hair_color" + edit_group_order="3" + name="Blonde Hair" + show_simple="true" + label_min="Black" + label_max="Blonde" + value_min="0" + value_max="1" + value_default=".5" + camera_elevation=".1" + camera_distance=".5"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="22, 6, 6, 255" /> + + <value + color="29, 9, 6, 255" /> + + <value + color="45, 21, 11, 255" /> + + <value + color="78, 39, 11, 255" /> + + <value + color="90, 53, 16, 255" /> + + <value + color="136, 92, 21, 255" /> + + <value + color="150, 106, 33, 255" /> + + <value + color="198, 156, 74, 255" /> + + <value + color="233, 192, 103, 255" /> + + <value + color="238, 205, 136, 255" /> + </param_color> + </param> + + <param + id="113" + group="0" + wearable="hair" + edit_group="hair_color" + edit_group_order="4" + name="Red Hair" + show_simple="true" + label_min="No Red" + label_max="Very Red" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="118, 47, 19, 255" /> + </param_color> + </param> + + <param + id="115" + group="0" + wearable="hair" + edit_group="hair_color" + edit_group_order="1" + name="White Hair" + show_simple="true" + label_min="No White" + label_max="All White" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 255, 255, 255" /> + </param_color> + </param> + + <param + id="112" + group="0" + wearable="hair" + edit_group="hair_color" + edit_group_order="2" + name="Rainbow Color" + show_simple="true" + label_min="None" + label_max="Wild" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".5"> + <param_color> + <value + color=" 0, 0, 0, 255" /> + + <value + color="255, 0, 255, 255" /> + + <value + color="255, 0, 0, 255" /> + + <value + color="255, 255, 0, 255" /> + + <value + color=" 0, 255, 0, 255" /> + + <value + color=" 0, 255, 255, 255" /> + + <value + color=" 0, 0, 255, 255" /> + + <value + color="255, 0, 255, 255" /> + </param_color> + </param> + </global_color> + + <!-- =========================================================== --> + <global_color + name="eye_color"> + <param + id="99" + group="0" + wearable="eyes" + edit_group="eyes" + edit_group_order="1" + name="Eye Color" + show_simple="true" + label_min="Natural" + label_max="Unnatural" + value_min="0" + value_max="1" + value_default="0" + camera_elevation=".1" + camera_distance=".3"> + <!-- default to natural brown eyes--> + <param_color> + <value + color="50, 25, 5, 255" /> + + <!-- natural dark brown eyes--> + <value + color="109, 55, 15, 255" /> + + <!-- natural brown eyes--> + <value + color="150, 93, 49, 255" /> + + <!-- natural light brown eyes--> + <value + color="152, 118, 25, 255" /> + + <!--natural hazel eyes--> + <value + color="95, 179, 107, 255" /> + + <!--natural green eyes--> + <value + color="87, 192, 191, 255" /> + + <!--natural aqua eyes--> + <value + color="95, 172, 179, 255" /> + + <!--natural blue eyes--> + <value + color="128, 128, 128, 255" /> + + <!--natural grey eyes--> + <value + color="0, 0, 0, 255" /> + + <!--black eyes--> + <value + color="255, 255, 0, 255" /> + + <!--bright yellow eyes--> + <value + color=" 0, 255, 0, 255" /> + + <!-- bright green eyes--> + <value + color=" 0, 255, 255, 255" /> + + <!-- bright cyan eyes--> + <value + color=" 0, 0, 255, 255" /> + + <!--bright blue eyes--> + <value + color="255, 0, 255, 255" /> + + <!-- bright violet eyes--> + <value + color="255, 0, 0, 255" /> + + <!--bright red eyes--> + </param_color> + </param> + + <param + id="98" + group="0" + wearable="eyes" + edit_group="eyes" + edit_group_order="2" + name="Eye Lightness" + show_simple="true" + label_min="Darker" + label_max="Lighter" + value_min="0" + value_max="1" + camera_elevation=".1" + camera_distance=".3"> + <param_color> + <value + color="0, 0, 0, 0" /> + + <value + color="255, 255, 255, 255" /> + </param_color> + </param> + </global_color> + + <!-- =========================================================== --> + <layer_set + body_region="hair" + width="512" + height="512" + clear_alpha="false"> + <layer + name="base" + global_color="hair_color" + write_all_channels="true"> + <texture + local_texture="hair_grain" /> + </layer> + + <layer + name="hair alpha" + visibility_mask="TRUE"> + <texture + local_texture="hair_alpha" /> + </layer> + + </layer_set> + <!-- =========================================================== --> + + <layer_set + body_region="head" + width="512" + height="512" + clear_alpha="false" + alpha_tga_file="head_alpha.tga"> + <layer + name="head bump base" + fixed_color = "128,128,128,255" + render_pass="bump"> + </layer> + + <layer + name="head bump definition" + render_pass="bump"> + + + <texture + tga_file="bump_head_base.tga" + file_is_mask="FALSE"/> <param - id="644" + id="873" group="1" - name="Hair_Forehead_Round" - wearable="hair" - edit_group="hair_style" + wearable="skin" + edit_group="driven" + edit_group_order="12" + name="Bump base" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + domain="0" /> </param> + </layer> + + <layer + name="base" + global_color="skin_color"> + <texture + tga_file="head_skingrain.tga" /> + </layer> + + <layer + name="headcolor"> + <texture + tga_file="head_color.tga" /> + </layer> + + <layer + name="shadow"> + <texture + tga_file="head_shading_alpha.tga" + file_is_mask="TRUE" /> <param - id="645" + id="158" group="1" - name="Hair_Forehead_Slant" - wearable="hair" - edit_group="hair_style" + wearable="skin" + name="Shading" value_min="0" value_max="1"> - <param_morph /> - </param> + <param_color> + <value + color="0, 0, 0, 0" /> - <param - id="774" - group="1" - name="Shear_Head_Hair" - wearable="hair" - edit_group="hair_style" - value_min="-2" - value_max="2"> - <param_morph /> + <value + color="0, 0, 0, 128" /> + </param_color> </param> + </layer> + + <layer + name="highlight"> + <texture + tga_file="head_highlights_alpha.tga" +file_is_mask="TRUE" /> + <param - id="771" - group="1" - name="Elongate_Head_Hair" - wearable="hair" - edit_group="hair_style" - value_min="-1" + id="159" + group="1" + name="Shading" + wearable="skin" + value_min="0" value_max="1"> - <param_morph /> - </param> + <param_color> + <value +color="255, 255, 255, 0" /> - <param - id="674" - group="0" - name="Hair_Shear_Back" - wearable="hair" - edit_group="hair_style" - edit_group_order="12" - label="Shear Back" - label_min="Full Back" - label_max="Sheared Back" - value_min="-1" - value_max="2" - value_default="-0.3" - camera_elevation=".1" - camera_distance=".5" - camera_angle="100"> - <param_morph /> - </param> - <param - id="762" - group="0" - name="Hair_Shear_Front" - wearable="hair" - edit_group="hair_style" - edit_group_order="11.8" - label="Shear Front" - show_simple="true" - label_min="Full Front" - label_max="Sheared Front" - value_min="0" - value_max="3" - camera_elevation=".1" - camera_distance=".5" - camera_angle="30"> - <param_morph /> + <value + color="255, 255, 255, 64" /> + </param_color> </param> + </layer> + <layer + name="rosyface"> + <texture + tga_file="rosyface_alpha.tga" + file_is_mask="true" /> <param - id="754" + id="116" group="0" - name="Hair_Taper_Back" - wearable="hair" - edit_group="hair_style" - edit_group_order="14" - label="Taper Back" - label_min="Wide Back" - label_max="Narrow Back" - value_min="-1" - value_max="2" - value_default="0" - camera_elevation=".1" - camera_distance=".5" - camera_angle="160"> - <param_morph /> - </param> + wearable="skin" + edit_group="skin_facedetail" + edit_group_order="4" + name="Rosy Complexion" + label_min="Less Rosy" + label_max="More Rosy" + value_min="0" + value_max="1" + camera_distance=".3" + camera_elevation=".07"> + <param_color> + <value + color="198, 71, 71, 0" /> - <param - id="755" - group="0" - name="Hair_Taper_Front" - wearable="hair" - edit_group="hair_style" - edit_group_order="13" - label="Taper Front" - label_min="Wide Front" - label_max="Narrow Front" - value_min="-1.5" - value_max="1.5" - value_default="0.05" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> + <value + color="198, 71, 71, 255" /> + </param_color> </param> + </layer> + + <layer + name="lips"> + <texture + tga_file="lips_mask.tga" + file_is_mask="true" /> <param - id="782" - group="1" - clothing_morph="true" - name="Hair_Pigtails_Short" - wearable="hair" - edit_group="hair_style" + id="117" + group="0" + wearable="skin" + edit_group="skin_facedetail" + edit_group_order="5" + name="Lip Pinkness" + label_min="Darker" + label_max="Pinker" value_min="0" - value_max="1"> - <param_morph /> + value_max="1" + camera_distance=".25"> + <param_color> + <value + color="220, 115, 115, 0" /> + + <value + color="220, 115, 115, 128" /> + </param_color> </param> + </layer> + <layer + name="wrinkles_shading" + render_pass="bump" + fixed_color="0,0,0,100"> <param - id="783" + id="118" group="1" - clothing_morph="true" - name="Hair_Pigtails_Med" - wearable="hair" - edit_group="hair_style" + wearable="skin" + name="Wrinkles" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + tga_file="bump_face_wrinkles.tga" + skip_if_zero="true" + domain="0.3" /> </param> + </layer> - <param - id="790" - group="1" - clothing_morph="true" - name="Hair_Pigtails_Medlong" - wearable="hair" - edit_group="hair_style" - value_min="0" - value_max="1"> - <param_morph /> + <!--<layer + name="wrinkles_highlights" + fixed_color="255,255,255,64"> + <param + id="128" + group="1" + name="Wrinkles" + value_min="0" + value_max="1"> + <param_alpha + tga_file="head_wrinkles_highlights_alpha.tga" + skip_if_zero="true" + domain="0.3" /> + </param> + </layer>--> + <layer + name="freckles" + fixed_color="120,47,20,128"> + <param + id="165" + group="0" + wearable="skin" + edit_group="skin_facedetail" + edit_group_order="2" + name="Freckles" + label_min="Less" + label_max="More" + value_min="0" + value_max="1" + camera_distance=".3" +camera_elevation=".07"> + <param_alpha + tga_file="freckles_alpha.tga" + skip_if_zero="true" +domain="0.5" /> </param> + </layer> + <layer +name="eyebrowsbump" +render_pass="bump"> + <texture + tga_file="head_hair.tga" + file_is_mask="false" /> <param - id="784" + id="1000" group="1" - clothing_morph="true" - name="Hair_Pigtails_Long" wearable="hair" - edit_group="hair_style" + edit_group="driven" + name="Eyebrow Size Bump" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + tga_file="eyebrows_alpha.tga" + domain="0.1" /> </param> <param - id="786" + id="1002" group="1" - name="Hair_Ponytail_Short" wearable="hair" - edit_group="hair_style" + edit_group="driven" + name="Eyebrow Density Bump" value_min="0" value_max="1"> - <param_morph /> + <param_color> + <value + color="255,255,255,0" /> + + <value + color="255,255,255,255" /> + </param_color> </param> + </layer> + + <layer + name="eyebrows" + global_color="hair_color"> + <texture + tga_file="head_hair.tga" + file_is_mask="false" /> <param - id="787" + id="1001" group="1" - name="Hair_Ponytail_Med" wearable="hair" - edit_group="hair_style" + edit_group="hair_eyebrows" + name="Eyebrow Size" + show_simple="true" value_min="0" - value_max="1"> - <param_morph /> + value_max="1" + value_default="0.5"> + <param_alpha + tga_file="eyebrows_alpha.tga" + domain="0.1" /> </param> <param - id="788" + id="1003" group="1" - name="Hair_Ponytail_Long" - clothing_morph="true" wearable="hair" - edit_group="hair_style" + edit_group="driven" + name="Eyebrow Density" value_min="0" value_max="1"> - <param_morph /> - </param> - -<!-- #end morph targets --> - </mesh> - - <mesh - type="hairMesh" - lod="1" - file_name="avatar_hair_1.llm" - min_pixel_width="160" - reference="avatar_hair.llm"> - </mesh> - - <mesh - type="hairMesh" - lod="2" - file_name="avatar_hair_2.llm" - min_pixel_width="80" - reference="avatar_hair.llm"> - </mesh> - - <mesh - type="hairMesh" - lod="3" - file_name="avatar_hair_3.llm" - min_pixel_width="40" - reference="avatar_hair.llm"> - </mesh> - - <mesh - type="hairMesh" - lod="4" - file_name="avatar_hair_4.llm" - min_pixel_width="20" - reference="avatar_hair.llm"> - </mesh> - - <mesh - type="hairMesh" - lod="5" - file_name="avatar_hair_5.llm" - min_pixel_width="0" - reference="avatar_hair.llm"> - </mesh> - - <mesh - type="headMesh" - lod="0" - file_name="avatar_head.llm" - min_pixel_width="320"> -<!-- - begin morph targets - ############# - tweakable morphs - ############# - --> - <param - id="1" - group="0" - name="Big_Brow" - label="Brow Size" - wearable="shape" - edit_group="shape_head" - edit_group_order="7" - label_min="Small" - label_max="Large" - value_min="-.3" - value_max="2" - camera_elevation=".1" - camera_distance=".4" - camera_angle="45"> - <param_morph /> - </param> + <param_color + operation="multiply"> + <value + color="255,255,255,0" /> - <param - id="2" - group="0" - name="Nose_Big_Out" - label="Nose Size" - wearable="shape" - edit_group="shape_nose" - edit_group_order="1" - label_min="Small" - label_max="Large" - show_simple="true" - value_min="-0.8" - value_max="2.5" - camera_elevation=".1" - camera_distance=".35" - camera_angle="50"> - <param_morph /> - </param> - - <param - id="4" - group="0" - name="Broad_Nostrils" - label="Nostril Width" - wearable="shape" - edit_group="shape_nose" - edit_group_order="3" - label_min="Narrow" - label_max="Broad" - value_min="-.5" - value_max="1" - camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> - <param_morph /> - </param> - - <param - id="759" - group="0" - name="Low_Septum_Nose" - label="Nostril Division" - wearable="shape" - edit_group="shape_nose" - edit_group_order="3.5" - label_min="High" - label_max="Low" - value_min="-1" - value_max="1.5" - value_default="0.5" - camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> - <param_morph /> + <value + color="255,255,255,255" /> + </param_color> </param> + </layer> + <layer + name="lipstick"> <param - id="517" + id="700" group="0" - name="Wide_Nose" - label="Nose Width" - wearable="shape" - edit_group="shape_nose" + wearable="skin" + edit_group="skin_makeup" edit_group_order="2" - label_min="Narrow" - label_max="Wide" - show_simple="true" - value_min="-.5" + name="Lipstick Color" + label_min="Pink" + label_max="Black" + value_min="0" value_max="1" - camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> - <param_morph /> - </param> + value_default=".25" + camera_distance=".25"> + <param_color> + <value + color="245,161,177,200" /> - <param - id="5" - group="0" - name="Cleft_Chin" - label="Chin Cleft" - wearable="shape" - edit_group="shape_chin" - edit_group_order="6" - label_min="Round" - label_max="Cleft" - value_min="-.1" - value_max="1" - camera_elevation="0" - camera_distance=".28" - camera_angle="-20"> - <param_morph /> - </param> + <value + color="216,37,67,200" /> - <param - id="6" - group="0" - name="Bulbous_Nose_Tip" - label="Nose Tip Shape" - wearable="shape" - edit_group="shape_nose" - edit_group_order="8" - label_min="Pointy" - label_max="Bulbous" - value_min="-.3" - value_max="1" - camera_elevation=".1" - camera_distance=".35" - camera_angle="15"> - <param_morph /> - </param> + <value + color="178,48,76,200" /> - <param - id="7" - group="0" - name="Weak_Chin" - label="Chin Angle" - wearable="shape" - edit_group="shape_chin" - edit_group_order="1" - label_min="Chin Out" - label_max="Chin In" - value_min="-.5" - value_max=".5" - camera_elevation=".1" - camera_distance=".4" - camera_angle="45"> - <param_morph /> - </param> + <value + color="68,0,11,200" /> - <param - id="8" - group="0" - name="Double_Chin" - label="Chin-Neck" - wearable="shape" - edit_group="shape_chin" - edit_group_order="8" - label_min="Tight Chin" - label_max="Double Chin" - value_min="-.5" - value_max="1.5" - camera_elevation="-.1" - camera_distance=".3" - camera_angle="60"> - <param_morph /> - </param> + <value + color="252,207,184,200" /> - <param - id="10" - group="0" - name="Sunken_Cheeks" - label="Lower Cheeks" - wearable="shape" - edit_group="shape_head" - edit_group_order="9" - label_min="Well-Fed" - label_max="Sunken" - show_simple="true" - value_min="-1.5" - value_max="3" - camera_elevation=".1" - camera_distance=".4" - camera_angle="5"> - <param_morph /> - </param> + <value + color="241,136,106,200" /> - <param - id="11" - group="0" - name="Noble_Nose_Bridge" - label="Upper Bridge" - wearable="shape" - edit_group="shape_nose" - edit_group_order="5" - label_min="Low" - label_max="High" - value_min="-.5" - value_max="1.5" - camera_elevation=".1" - camera_distance=".35" - camera_angle="70"> - <param_morph /> - </param> + <value + color="208,110,85,200" /> - <param - id="758" - group="0" - name="Lower_Bridge_Nose" - label="Lower Bridge" - wearable="shape" - edit_group="shape_nose" - edit_group_order="5.5" - label_min="Low" - label_max="High" - value_min="-1.5" - value_max="1.5" - camera_elevation=".1" - camera_distance=".35" - camera_angle="70"> - <param_morph /> - </param> + <value + color="106,28,18,200" /> - <param - id="12" - group="0" - name="Jowls" - wearable="shape" - edit_group="shape_chin" - edit_group_order="5" - label_min="Less" - label_max="More" - value_min="-.5" - value_max="2.5" - camera_elevation=".1" - camera_distance=".4" - camera_angle="0"> - <param_morph /> + <value + color="58,26,49,200" /> + + <value + color="14,14,14,200" /> + </param_color> </param> <param - id="13" + id="701" group="0" - name="Cleft_Chin_Upper" - label="Upper Chin Cleft" - wearable="shape" - edit_group="shape_chin" - edit_group_order="7" - label_min="Round" - label_max="Cleft" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="1" + name="Lipstick" + label_min="No Lipstick" + label_max="More Lipstick" value_min="0" - value_max="1.5" - camera_elevation="0" - camera_distance=".28" - camera_angle="-20"> - <param_morph /> + value_max=".9" + value_default="0.0" + camera_distance=".25"> + <param_alpha + tga_file="lipstick_alpha.tga" + skip_if_zero="true" + domain="0.05" /> </param> + </layer> + <layer + name="lipgloss" + fixed_color="255,255,255,190"> <param - id="14" + id="702" + name="Lipgloss" + label_min="No Lipgloss" + label_max="Glossy" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="3" group="0" - name="High_Cheek_Bones" - label="Cheek Bones" - wearable="shape" - edit_group="shape_head" - edit_group_order="10" - label_min="Low" - label_max="High" - value_min="-.5" + value_min="0" value_max="1" - camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> - <param_morph /> + camera_distance=".25"> + <param_alpha + tga_file="lipgloss_alpha.tga" + skip_if_zero="true" + domain="0.2" /> </param> + </layer> + <layer + name="blush"> <param - id="15" + id="704" group="0" - name="Ears_Out" - label="Ear Angle" - wearable="shape" - edit_group="shape_ears" - edit_group_order="2" - label_min="In" - label_max="Out" - value_min="-.5" - value_max="1.5" - camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> - <param_morph /> - </param> - -<!--Pointy eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1--> - <param - id="870" - group="1" - name="Pointy_Eyebrows" - label="Eyebrow Points" - wearable="hair" - edit_group="hair_eyebrows" + wearable="skin" + edit_group="skin_makeup" edit_group_order="4" - label_min="Smooth" - label_max="Pointy" - value_min="-.5" - value_max="1" - camera_elevation=".1" - camera_distance=".3"> - <param_morph /> + name="Blush" + label_min="No Blush" + label_max="More Blush" + value_min="0" + value_max=".9" + value_default="0" + camera_distance=".3" + camera_elevation=".07" + camera_angle="20"> + <param_alpha + tga_file="blush_alpha.tga" + skip_if_zero="true" + domain="0.3" /> </param> <param - id="17" + id="705" group="0" - name="Square_Jaw" - label="Jaw Shape" - wearable="shape" - edit_group="shape_chin" - edit_group_order="2" - label_min="Pointy" - label_max="Square" - value_min="-.5" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="5" + name="Blush Color" + label_min="Pink" + label_max="Orange" + value_min="0" value_max="1" + value_default=".5" camera_distance=".3" - camera_elevation=".04" - camera_angle="-20"> - <param_morph /> - </param> + camera_elevation=".07" + camera_angle="20"> + <param_color> + <value + color="253,162,193,200" /> - <param - id="18" - group="0" - name="Puffy_Upper_Cheeks" - label="Upper Cheeks" - wearable="shape" - edit_group="shape_head" - edit_group_order="8" - label_min="Thin" - label_max="Puffy" - value_min="-1.5" - value_max="2.5" - camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> - <param_morph /> - </param> + <value + color="247,131,152,200" /> - <param - id="19" - group="0" - name="Upturned_Nose_Tip" - label="Nose Tip Angle" - wearable="shape" - edit_group="shape_nose" - edit_group_order="7" - label_min="Downturned" - label_max="Upturned" - value_min="-1.5" - value_max="1" - camera_elevation=".1" - camera_distance=".35" - camera_angle="15"> - <param_morph /> - </param> + <value + color="213,122,140,200" /> - <param - id="20" - group="0" - name="Bulbous_Nose" - label="Nose Thickness" - wearable="shape" - edit_group="shape_nose" - edit_group_order="4" - label_min="Thin Nose" - label_max="Bulbous Nose" - show_simple="true" - value_min="-.5" - value_max="1.5" - camera_elevation=".1" - camera_distance=".3"> - <param_morph /> - </param> + <value + color="253,152,144,200" /> - <param - id="21" - group="0" - name="Upper_Eyelid_Fold" - label="Upper Eyelid Fold" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="5" - label_min="Uncreased" - label_max="Creased" - value_min="-0.2" - value_max="1.3" - camera_elevation=".1" - camera_distance=".35"> - <param_morph /> + <value + color="236,138,103,200" /> + + <value + color="195,128,122,200" /> + + <value + color="148,103,100,200" /> + + <value + color="168,95,62,200" /> + </param_color> </param> <param - id="22" + id="711" group="0" - name="Attached_Earlobes" - label="Attached Earlobes" - wearable="shape" - edit_group="shape_ears" - edit_group_order="3" - label_min="Unattached" - label_max="Attached" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="6" + name="Blush Opacity" + label_min="Clear" + label_max="Opaque" value_min="0" value_max="1" - camera_elevation=".1" + value_default=".5" camera_distance=".3" - camera_angle="45"> - <param_morph /> - </param> + camera_elevation=".07" + camera_angle="20"> + <param_color + operation="multiply"> + <value + color="255,255,255,0" /> - <param - id="23" - group="0" - name="Baggy_Eyes" - label="Eye Bags" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="6" - label_min="Smooth" - label_max="Baggy" - value_min="-.5" - value_max="1.5" - camera_elevation=".1" - camera_distance=".35"> - <param_morph /> + <value + color="255,255,255,255" /> + </param_color> </param> + </layer> + <layer + name="Outer Eye Shadow"> <param - id="765" + id="708" group="0" - name="Puffy_Lower_Lids" - label="Puffy Eyelids" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="6.1" - label_min="Flat" - label_max="Puffy" - value_min="-.3" - value_max="2.5" - camera_elevation=".1" - camera_distance=".35"> - <param_morph /> - </param> + wearable="skin" + edit_group="skin_makeup" + edit_group_order="11" + name="Out Shdw Color" + label_min="Light" + label_max="Dark" + value_min="0" + value_max="1" + camera_distance=".3" + camera_elevation=".14"> + <param_color> + <value + color="252,247,246,255" /> - <param - id="24" - group="0" - name="Wide_Eyes" - label="Eye Opening" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="1.1" - label_min="Narrow" - label_max="Wide" - value_min="-1.5" - value_max="2" - show_simple="true" - camera_elevation=".1" - camera_distance=".35"> - <param_morph /> - </param> + <value + color="255,206,206,255" /> - <param - id="25" - group="0" - name="Wide_Lip_Cleft" - label="Lip Cleft" - wearable="shape" - edit_group="shape_mouth" - edit_group_order="6" - label_min="Narrow" - label_max="Wide" - value_min="-.8" - value_max="1.5" - camera_elevation="0" - camera_distance=".28"> - <param_morph /> - </param> + <value + color="233,135,149,255" /> - <param - id="764" - group="0" - name="Lip_Cleft_Deep" - label="Lip Cleft Depth" - wearable="shape" - edit_group="shape_mouth" - edit_group_order="5.8" - label_min="Shallow" - label_max="Deep" - value_min="-.5" - value_max="1.2" - camera_elevation="0" - camera_distance=".28"> - <param_morph /> - </param> + <value + color="220,168,192,255" /> - <param - id="26" - group="1" - wearable="shape" - name="Lips_Thin" - edit_group="driven" - value_min="0" - value_max=".7"> - <param_morph /> - </param> + <value + color="228,203,232,255" /> - <param - id="27" - group="0" - name="Wide_Nose_Bridge" - label="Bridge Width" - wearable="shape" - edit_group="shape_nose" - edit_group_order="6" - label_min="Narrow" - label_max="Wide" - value_min="-1.3" - value_max="1.2" - camera_elevation=".1" - camera_distance=".3" - camera_angle="-20"> - <param_morph /> - </param> + <value + color="255,234,195,255" /> - <param - id="28" - group="1" - name="Lips_Fat" - wearable="shape" - edit_group="driven" - value_min="0" - value_max="2"> - <param_morph /> - </param> + <value + color="230,157,101,255" /> - <param - id="29" - group="1" - name="Wide_Upper_Lip" - wearable="shape" - edit_group="driven" - value_min="-.7" - value_max="1.3"> - <param_morph /> - </param> + <value + color="255,147,86,255" /> - <param - id="30" - group="1" - name="Wide_Lower_Lip" - wearable="shape" - edit_group="driven" - value_min="-.7" - value_max="1.3"> - <param_morph /> - </param> + <value + color="228,110,89,255" /> -<!--Arced eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1--> - <param - id="872" - group="1" - name="Arced_Eyebrows" - label="Eyebrow Arc" - wearable="hair" - edit_group="hair_eyebrows" - edit_group_order="3" - label_min="Flat" - label_max="Arced" - value_min="0" - value_max="1"> - <param_morph /> - </param> + <value + color="228,150,120,255" /> -<!--Lower eyebrows became a driver/driven param with new min value for backwards compatibility between 1.0 and 1.1--> - <param - id="871" - group="1" - name="Lower_Eyebrows" - label="Eyebrow Height" - show_simple="true" - wearable="hair" - edit_group="hair_eyebrows" - edit_group_order="2.5" - label_min="Higher" - label_max="Lower" - value_min="-2" - value_max="2"> - <param_morph /> + <value + color="223,227,213,255" /> + + <value + color="96,116,87,255" /> + + <value + color="88,143,107,255" /> + + <value + color="194,231,223,255" /> + + <value + color="207,227,234,255" /> + + <value + color="41,171,212,255" /> + + <value + color="180,137,130,255" /> + + <value + color="173,125,105,255" /> + + <value + color="144,95,98,255" /> + + <value + color="115,70,77,255" /> + + <value + color="155,78,47,255" /> + + <value + color="239,239,239,255" /> + + <value + color="194,194,194,255" /> + + <value + color="120,120,120,255" /> + + <value + color="10,10,10,255" /> + </param_color> </param> <param - id="35" + id="706" group="0" - name="Big_Ears" - label="Ear Size" - wearable="shape" - edit_group="shape_ears" - edit_group_order="1" - label_min="Small" - label_max="Large" - value_min="-1" - value_max="2" - camera_elevation=".1" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="12" + name="Out Shdw Opacity" + label_min="Clear" + label_max="Opaque" + value_min=".2" + value_max="1" + value_default=".6" camera_distance=".3" - camera_angle="45"> - <param_morph /> + camera_elevation=".14"> + <param_color + operation="multiply"> + <value + color="255,255,255,0" /> + + <value + color="255,255,255,255" /> + </param_color> </param> <param - id="796" + id="707" group="0" - name="Pointy_Ears" - label="Ear Tips" - wearable="shape" - edit_group="shape_ears" - edit_group_order="4" - label_min="Flat" - label_max="Pointy" - value_min="-.4" - value_max="3" - camera_elevation=".1" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="10" + name="Outer Shadow" + label_min="No Eyeshadow" + label_max="More Eyeshadow" + value_min="0" + value_max=".7" camera_distance=".3" - camera_angle="45"> - <param_morph /> + camera_elevation=".14"> + <param_alpha + tga_file="eyeshadow_outer_alpha.tga" + skip_if_zero="true" + domain="0.05" /> </param> + </layer> + <layer + name="Inner Eye Shadow"> <param - id="185" + id="712" group="0" - name="Deep_Chin" - label="Chin Depth" - wearable="shape" - edit_group="shape_chin" - edit_group_order="3" - label_min="Shallow" - label_max="Deep" - value_min="-1" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="8" + name="In Shdw Color" + label_min="Light" + label_max="Dark" + value_min="0" value_max="1" - camera_elevation=".1" - camera_distance=".4" - camera_angle="30"> - <param_morph /> - </param> + camera_distance=".3" + camera_elevation=".14"> + <param_color> + <value + color="252,247,246,255" /> - <param - id="186" - group="1" - name="Egg_Head" - label="Egg Head" - wearable="shape" - edit_group="shape_head" - label_min="Chin Heavy" - label_max="Forehead Heavy" - value_min="-1.3" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + <value + color="255,206,206,255" /> - <param - id="187" - group="1" - name="Squash_Stretch_Head" - label="Squash/Stretch Head" - wearable="shape" - edit_group="shape_head" - label_min="Squash Head" - label_max="Stretch Head" - value_min="-.5" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph> - <volume_morph - name="HEAD" - scale="-0.008 -0.006 0.015"/> - </param_morph> - </param> + <value + color="233,135,149,255" /> - <param - id="188" - group="1" - name="Square_Head" - wearable="shape" - label_min="Less Square" - label_max="More Square" - value_min="0" - value_max=".7" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + <value + color="220,168,192,255" /> - <param - id="189" - group="1" - wearable="shape" - name="Round_Head" - label_min="Less Round" - label_max="More Round" - value_min="0" - value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> - </param> + <value + color="228,203,232,255" /> - <param - id="194" - group="1" - name="Eye_Spread" - wearable="shape" - edit_group="shape_eyes" - label_min="Eyes Together" - label_max="Eyes Spread" - value_min="-2" - value_max="2"> - <param_morph /> - </param> + <value + color="255,234,195,255" /> - <param - id="400" - sex="male" - group="1" - name="Displace_Hair_Facial" - label="Hair Thickess" - wearable="hair" - edit_group="hair_facial" - label_min="Cropped Hair" - label_max="Bushy Hair" - value_min="0" - value_max="2"> - <param_morph /> - </param> + <value + color="230,157,101,255" /> - <param - id="506" - group="0" - name="Mouth_Height" - wearable="shape" - label="Mouth Position" - show_simple="true" - edit_group="shape_mouth" - edit_group_order="4" - label_min="High" - label_max="Low" - value_min="-2" - value_max="2" - camera_distance=".3" - camera_elevation=".04"> - <param_morph /> - </param> + <value + color="255,147,86,255" /> - <param - id="633" - group="1" - name="Fat_Head" - label="Fat Head" - wearable="shape" - edit_group="shape_body" - label_min="Skinny" - label_max="Fat" - value_min="0" - value_max="1" - camera_elevation=".3"> - <param_morph/> - </param> + <value + color="228,110,89,255" /> - <param - id="630" - group="1" - name="Forehead_Round" - label="Round Forehead" - wearable="shape" - label_min="Less" - label_max="More" - value_min="0" - value_max="1"> - <param_morph /> - </param> + <value + color="228,150,120,255" /> - <param - id="631" - group="1" - name="Forehead_Slant" - label="Slanted Forehead" - wearable="shape" - label_min="Less" - label_max="More" - value_min="0" - value_max="1"> - <param_morph /> - </param> + <value + color="223,227,213,255" /> - <param - id="650" - group="0" - name="Eyelid_Corner_Up" - label="Outer Eye Corner" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="4" - label_min="Corner Down" - label_max="Corner Up" - value_min="-1.3" - value_max="1.2" - camera_elevation=".1" - camera_distance=".30"> - <param_morph /> - </param> + <value + color="96,116,87,255" /> - <param - id="880" - group="0" - name="Eyelid_Inner_Corner_Up" - label="Inner Eye Corner" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="4.2" - label_min="Corner Down" - label_max="Corner Up" - value_min="-1.3" - value_max="1.2" - camera_elevation=".1" - camera_distance=".30"> - <param_morph /> - </param> - - <param - id="653" - group="0" - name="Tall_Lips" - wearable="shape" - label="Lip Fullness" - show_simple="true" - edit_group="shape_mouth" - edit_group_order="2" - label_min="Less Full" - label_max="More Full" - value_min="-1" - value_max="2" - camera_distance=".3" - camera_elevation=".04"> - <param_morph /> + <value + color="88,143,107,255" /> + + <value + color="194,231,223,255" /> + + <value + color="207,227,234,255" /> + + <value + color="41,171,212,255" /> + + <value + color="180,137,130,255" /> + + <value + color="173,125,105,255" /> + + <value + color="144,95,98,255" /> + + <value + color="115,70,77,255" /> + + <value + color="155,78,47,255" /> + + <value + color="239,239,239,255" /> + + <value + color="194,194,194,255" /> + + <value + color="120,120,120,255" /> + + <value + color="10,10,10,255" /> + </param_color> </param> <param - id="656" + id="713" group="0" - name="Crooked_Nose" - wearable="shape" - label="Crooked Nose" - edit_group="shape_nose" + wearable="skin" + edit_group="skin_makeup" edit_group_order="9" - label_min="Nose Left" - label_max="Nose Right" - value_min="-2" - value_max="2" + name="In Shdw Opacity" + label_min="Clear" + label_max="Opaque" + value_min=".2" + value_max="1" + value_default=".7" camera_distance=".3" - camera_elevation=".04" - camera_angle="-20"> - <param_morph /> - </param> + camera_elevation=".14"> + <param_color + operation="multiply"> + <value + color="255,255,255,0" /> - <param - id="657" - group="1" - name="Smile_Mouth" - wearable="shape" - label="Mouth Corner" - edit_group="shape_mouth" - label_min="Corner Normal" - label_max="Corner Up" - value_min="0" - value_max="1.4" - camera_distance=".3" - camera_elevation=".04"> - <param_morph /> + <value + color="255,255,255,255" /> + </param_color> </param> <param - id="658" - group="1" - name="Frown_Mouth" - wearable="shape" - label="Mouth Corner" - edit_group="shape_mouth" - label_min="Corner Normal" - label_max="Corner Down" + id="709" + group="0" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="7" + name="Inner Shadow" + label_min="No Eyeshadow" + label_max="More Eyeshadow" value_min="0" - value_max="1.2" + value_max="1" + value_default="0" camera_distance=".3" - camera_elevation=".04"> - <param_morph /> + camera_elevation=".14"> + <param_alpha + tga_file="eyeshadow_inner_alpha.tga" + skip_if_zero="true" + domain="0.2" /> </param> + </layer> + <layer + name="eyeliner" + fixed_color="0,0,0,200"> <param - id="797" - group="1" - name="Fat_Upper_Lip" - wearable="shape" - label="Fat Upper Lip" - edit_group="shape_mouth" - label_min="Normal Upper" - label_max="Fat Upper" + id="703" + group="0" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="13" + name="Eyeliner" + label_min="No Eyeliner" + label_max="Full Eyeliner" value_min="0" - value_max="1.5" + value_max="1" + value_default="0.0" camera_distance=".3" - camera_elevation=".04"> - <param_morph /> + camera_elevation=".14"> + <param_alpha + tga_file="eyeliner_alpha.tga" + skip_if_zero="true" + domain="0.1" /> </param> <param - id="798" - group="1" - name="Fat_Lower_Lip" - wearable="shape" - label="Fat Lower Lip" - edit_group="shape_mouth" - label_min="Normal Lower" - label_max="Fat Lower" + id="714" + group="0" + wearable="skin" + edit_group="skin_makeup" + edit_group_order="14" + name="Eyeliner Color" + label_min="Dark Green" + label_max="Black" value_min="0" - value_max="1.5" + value_max="1" camera_distance=".3" - camera_elevation=".04"> - <param_morph /> - </param> + camera_elevation=".14"> + <param_color> + <value + color="24,98,40,250" /> - <param - id="660" - group="1" - name="Shear_Head" - wearable="shape" - label="Shear Face" - edit_group="shape_head" - label_min="Shear Left" - label_max="Shear Right" - value_min="-2" - value_max="2" - value_default="0" - camera_distance=".5" - camera_elevation=".04"> - <param_morph /> - </param> + <!-- dark green --> + <value + color="9,100,127,250" /> - <param - id="770" - group="1" - name="Elongate_Head" - wearable="shape" - label="Shear Face" - edit_group="shape_head" - label_min="Flat Head" - label_max="Long Head" - value_min="-1" - value_max="1" - value_default="0" - camera_distance=".5" - camera_elevation=".04"> - <param_morph> - <volume_morph - name="HEAD" - scale="0.02 0.0 0.0"/> - </param_morph> - </param> + <!-- lt.aqua blue --> + <value + color="61,93,134,250" /> - <param - id="663" - group="0" - name="Shift_Mouth" - wearable="shape" - label="Shift Mouth" - edit_group="shape_mouth" - edit_group_order="7" - label_min="Shift Left" - label_max="Shift Right" - value_min="-2" - value_max="2" - value_default="0" - camera_distance=".35" - camera_elevation=".04" - camera_angle="-20"> - <param_morph /> - </param> + <!-- aqua --> + <value + color="70,29,27,250" /> - <param - id="664" - group="0" - name="Pop_Eye" - wearable="shape" - label="Eye Pop" - edit_group="shape_eyes" - edit_group_order="8" - label_min="Pop Right Eye" - label_max="Pop Left Eye" - value_min="-1.3" - value_max="1.3" - value_default="0" - camera_elevation=".1" - camera_distance=".35"> - <param_morph /> - </param> + <!-- dark brown --> + <value + color="115,75,65,250" /> - <param - id="760" - group="0" - name="Jaw_Angle" - wearable="shape" - label="Jaw Angle" - edit_group="shape_chin" - edit_group_order="3.5" - label_min="Low Jaw" - label_max="High Jaw" - value_min="-1.2" - value_max="2" - value_default="0" - camera_distance=".5" - camera_elevation=".04" - camera_angle="70"> - <param_morph /> - </param> + <!-- lt. brown blue --> + <value + color="100,100,100,250" /> - <param - id="665" - group="0" - name="Jaw_Jut" - wearable="shape" - label="Jaw Jut" - edit_group="shape_chin" - edit_group_order="4" - label_min="Overbite" - label_max="Underbite" - value_min="-2" - value_max="2" - value_default="0" - camera_distance=".5" - camera_elevation=".04" - camera_angle="70"> - <param_morph /> - </param> + <!-- grey --> + <value + color="91,80,74,250" /> - <param - id="686" - group="1" - name="Head_Eyes_Big" - wearable="shape" - label="Eye Size" - edit_group="shape_eyes" - label_min="Beady Eyes" - label_max="Anime Eyes" - show_simple="true" - value_min="-2" - value_max="2" - value_default="0"> - <param_morph /> - </param> + <!-- grey/brown --> + <value + color="112,42,76,250" /> - <param - id="767" - group="1" - name="Bug_Eyed_Head" - wearable="shape" - label="Eye Depth" - edit_group="shape_eyes" - edit_group_order="4.5" - label_min="Sunken Eyes" - label_max="Bug Eyes" - value_min="-2" - value_max="2" - value_default="0"> - <param_morph /> - </param> + <!-- plum --> + <value + color="14,14,14,250" /> -<!-- - #Fat_Lips = Fat_Lips 34 1 0 1 - #Wide_Lips = Wide_Lips 35 1 0 1 - #Wide_Nose = Wide_Nose 36 1 0 1 - --> -<!-- - ############## - # Facial Expression morphs - ############## - --> - <param - id="300" - group="1" - name="Express_Closed_Mouth" - value_default="1" - value_min="0" - value_max="1"> - <param_morph /> + <!-- black --> + </param_color> </param> + </layer> - <param - id="301" - group="1" - name="Express_Tongue_Out" - value_min="0" - value_max="1"> - <param_morph /> - </param> + <layer + name="facialhair bump" + render_pass="bump"> + <texture + tga_file="head_hair.tga" + file_is_mask="false" /> <param - id="302" + id="1004" + sex="male" group="1" - name="Express_Surprise_Emote" + wearable="hair" + edit_group="driven" + name="Sideburns bump" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + tga_file="facehair_sideburns_alpha.tga" + skip_if_zero="true" + domain="0.05" /> </param> <param - id="303" + id="1006" + sex="male" group="1" - name="Express_Wink_Emote" + wearable="hair" + edit_group="driven" + name="Moustache bump" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + tga_file="facehair_moustache_alpha.tga" + skip_if_zero="true" + domain="0.05" /> </param> <param - id="304" + id="1008" + sex="male" group="1" - name="Express_Embarrassed_Emote" + wearable="hair" + edit_group="driven" + name="Soulpatch bump" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + tga_file="facehair_soulpatch_alpha.tga" + skip_if_zero="true" + domain="0.1" /> </param> <param - id="305" + id="1010" + sex="male" group="1" - name="Express_Shrug_Emote" + edit_group="driven" + wearable="hair" + name="Chin Curtains bump" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + tga_file="facehair_chincurtains_alpha.tga" + skip_if_zero="true" + domain="0.03" /> </param> <param - id="306" + id="1012" group="1" - name="Express_Kiss" + sex="male" + wearable="hair" + edit_group="driven" + name="5 O'Clock Shadow bump" value_min="0" value_max="1"> - <param_morph /> - </param> + <param_color> + <value + color="255,255,255,255" /> - <param - id="307" - group="1" - name="Express_Bored_Emote" - value_min="0" - value_max="1"> - <param_morph /> + <value + color="255,255,255,0" /> + </param_color> </param> + </layer> - <param - id="308" - group="1" - name="Express_Repulsed_Emote" - value_min="0" - value_max="1"> - <param_morph /> - </param> + <layer + name="facialhair" + global_color="hair_color"> - <param - id="309" - group="1" - name="Express_Disdain" - value_min="0" - value_max="1"> - <param_morph /> - </param> + <texture + tga_file="head_hair.tga" + file_is_mask="false" /> <param - id="310" + id="1005" + sex="male" group="1" - name="Express_Afraid_Emote" + wearable="hair" + edit_group="driven" + name="Sideburns" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + tga_file="facehair_sideburns_alpha.tga" + skip_if_zero="true" + domain="0.05" /> </param> <param - id="311" + id="1007" + sex="male" group="1" - name="Express_Worry_Emote" + wearable="hair" + edit_group="driven" + name="Moustache" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + tga_file="facehair_moustache_alpha.tga" + skip_if_zero="true" + domain="0.05" /> </param> <param - id="312" + id="1009" + sex="male" group="1" - name="Express_Cry_Emote" + wearable="hair" + edit_group="driven" + name="Soulpatch" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + tga_file="facehair_soulpatch_alpha.tga" + skip_if_zero="true" + domain="0.1" /> </param> <param - id="313" + id="1011" + sex="male" group="1" - name="Express_Sad_Emote" + wearable="hair" + edit_group="driven" + name="Chin Curtains" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + tga_file="facehair_chincurtains_alpha.tga" + skip_if_zero="true" + domain="0.03" /> </param> <param - id="314" + id="751" group="1" - name="Express_Anger_Emote" + wearable="hair" + sex="male" + edit_group="hair_facial" + name="5 O'Clock Shadow" + label_min="Dense hair" + label_max="Shadow hair" value_min="0" - value_max="1"> - <param_morph /> - </param> + value_max="1" + value_default="0.7" + camera_elevation=".1" + camera_distance=".3"> + <param_color + operation="multiply"> + <value + color="255,255,255,255" /> - <param - id="315" - group="1" - name="Express_Frown" - value_min="0" - value_max="1"> - <param_morph /> + <value + color="255,255,255,30" /> + </param_color> </param> + </layer> - <param - id="316" - group="1" - name="Express_Laugh_Emote" - value_min="0" - value_max="1"> - <param_morph /> - </param> + <layer + name="head_bodypaint"> + <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> + + <!-- =========================================================== --> + <layer_set + body_region="upper_body" + width="512" + height="512"> + <layer + name="base_upperbody bump" + render_pass="bump" + fixed_color="128,128,128,255"> + </layer> + <layer + name="upperbody bump definition" + render_pass="bump"> + <texture + tga_file="bump_upperbody_base.tga" + file_is_mask="FALSE"/> <param - id="317" + id="874" group="1" - name="Express_Toothsmile" + wearable="skin" + edit_group="driven" + edit_group_order="20" + name="Bump upperdef" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + domain="0" /> </param> + </layer> + + <layer + name="base" + global_color="skin_color"> + <texture + tga_file="body_skingrain.tga" /> + </layer> + + <layer + name="nipples"> + <texture + tga_file="upperbody_color.tga" /> + </layer> + + <layer + name="shadow"> + <texture + tga_file="upperbody_shading_alpha.tga" + file_is_mask="TRUE" /> <param - id="318" + id="125" group="1" - name="Express_Smile" + name="Shading" + wearable="skin" value_min="0" value_max="1"> - <param_morph /> + <param_color> + <value + color="0, 0, 0, 0" /> + + <value + color="0, 0, 0, 128" /> + </param_color> </param> + </layer> + + <layer + name="highlight"> + <texture + tga_file="upperbody_highlights_alpha.tga" + file_is_mask="TRUE" /> <param - id="632" + id="126" group="1" - name="Express_Open_Mouth" + wearable="skin" + name="Shading" value_min="0" value_max="1"> - <param_morph /> + <param_color> + <value + color="255, 255, 255, 0" /> + + <value + color="255, 255, 255, 64" /> + </param_color> </param> + </layer> -<!-- - ############## - # Lipsync morphs - ############## - --> + <layer + name="upper_bodypaint"> + <texture + local_texture="upper_bodypaint" /> + </layer> + <layer + name="freckles upper" + fixed_color="120,47,20,128"> <param - id="70" + id="776" group="1" - name="Lipsync_Aah" + name="freckles upper" + wearable="skin" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + tga_file="upperbodyfreckles_alpha.tga" + skip_if_zero="true" + domain="0.6" /> </param> + </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"> + <texture + local_texture="upper_undershirt" + local_texture_alpha_only="true" /> <param - id="71" + id="1043" group="1" - name="Lipsync_Ooh" - value_min="0" - value_max="1"> - <param_morph /> + wearable="undershirt" + edit_group="driven" + name="Sleeve Length bump" + value_min=".01" + value_max="1" + value_default=".4"> + <param_alpha + tga_file="shirt_sleeve_alpha.tga" + multiply_blend="false" + domain="0.01" /> </param> -<!-- - ############## - # other morphs (not user controlled) - ############## - --> <param - id="40" + id="1045" group="1" - name="Male_Head" + wearable="undershirt" + edit_group="undershirt" + edit_group_order="2" + name="Bottom bump" value_min="0" - value_max="1"> - <param_morph /> + value_max="1" + value_default=".8"> + <param_alpha + tga_file="shirt_bottom_alpha.tga" + multiply_blend="true" + domain="0.05" /> </param> <param - id="41" + id="1047" group="1" - name="Old" + wearable="undershirt" + edit_group="driven" + name="Collar Front bump" value_min="0" - value_max="1"> - <param_morph /> + value_max="1" + value_default=".8"> + <param_alpha + tga_file="shirt_collar_alpha.tga" + multiply_blend="true" + domain="0.05" /> </param> -<!-- - ############## - # animatable morphs - ############## - --> <param - id="51" + id="1049" group="1" - name="Furrowed_Eyebrows" + wearable="undershirt" + edit_group="driven" + name="Collar Back bump" value_min="0" - value_max="1"> - <param_morph /> + value_max="1" + value_default=".8"> + <param_alpha + tga_file="shirt_collar_back_alpha.tga" + multiply_blend="true" + domain="0.05" /> </param> + </layer> + + <layer + name="upper_undershirt"> + <texture + local_texture="upper_undershirt" /> <param - id="53" - group="1" - name="Surprised_Eyebrows" + id="821" + group="0" + wearable="undershirt" + edit_group="colorpicker" + name="undershirt_red" value_min="0" - value_max="1"> - <param_morph /> + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> </param> <param - id="54" - group="1" - name="Worried_Eyebrows" + id="822" + group="0" + wearable="undershirt" + edit_group="colorpicker" + name="undershirt_green" value_min="0" - value_max="1"> - <param_morph /> + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> </param> <param - id="55" - group="1" - name="Frown_Mouth" + id="823" + group="0" + wearable="undershirt" + edit_group="colorpicker" + name="undershirt_blue" value_min="0" - value_max="1"> - <param_morph /> + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> </param> <param - id="57" + id="1042" group="1" - name="Smile_Mouth" - value_min="0" - value_max="1"> - <param_morph /> + wearable="undershirt" + edit_group="driven" + name="Sleeve Length" + value_min=".01" + value_max="1" + value_default=".4"> + <param_alpha + tga_file="shirt_sleeve_alpha.tga" + multiply_blend="false" + domain="0.01" /> </param> <param - id="58" + id="1044" group="1" - name="Blink_Left" + wearable="undershirt" + edit_group="driven" + name="Bottom" value_min="0" - value_max="1"> - <param_morph /> + value_max="1" + value_default=".8"> + <param_alpha + tga_file="shirt_bottom_alpha.tga" + multiply_blend="true" + domain="0.05" /> </param> <param - id="59" + id="1046" group="1" - name="Blink_Right" + wearable="undershirt" + edit_group="driven" + name="Collar Front" value_min="0" - value_max="1"> - <param_morph /> - </param> - -<!-- - #end morph targets - --> - </mesh> - - <mesh - type="headMesh" - lod="1" - file_name="avatar_head_1.llm" - min_pixel_width="160" - reference="avatar_head.llm"> - </mesh> - - <mesh - type="headMesh" - lod="2" - file_name="avatar_head_2.llm" - min_pixel_width="80" - reference="avatar_head.llm"> - </mesh> - - <mesh - type="headMesh" - lod="3" - file_name="avatar_head_3.llm" - min_pixel_width="40" - reference="avatar_head.llm"> - </mesh> - - <mesh - type="headMesh" - lod="4" - file_name="avatar_head_4.llm" - min_pixel_width="0" - reference="avatar_head.llm"> - </mesh> - - <mesh - type="eyelashMesh" - lod="0" - file_name="avatar_eyelashes.llm" - min_pixel_width="320"> - <param - shared="1" - id="660" - group="1" - name="Shear_Head" - wearable="shape" - label="Shear Face" - edit_group="shape_head" - label_min="Shear Left" - label_max="Shear Right" - value_min="-2" - value_max="2" - value_default="0" - camera_distance=".5" - camera_elevation=".04"> - <param_morph /> + value_max="1" + value_default=".8"> + <param_alpha + tga_file="shirt_collar_alpha.tga" + multiply_blend="true" + domain="0.05" /> </param> <param - shared="1" - id="770" + id="1048" group="1" - name="Elongate_Head" - wearable="shape" - label="Shear Face" - edit_group="shape_head" - label_min="Flat Head" - label_max="Long Head" - value_min="-1" + wearable="undershirt" + edit_group="driven" + name="Collar Back" + label_min="Low" + label_max="High" + value_min="0" value_max="1" - value_default="0" - camera_distance=".5" - camera_elevation=".04"> - <param_morph /> + value_default=".8"> + <param_alpha + tga_file="shirt_collar_back_alpha.tga" + multiply_blend="true" + domain="0.05" /> </param> + </layer> + <layer + name="Nail Polish"> <param - shared="1" - id="664" + id="710" group="0" - name="Pop_Eye" - wearable="shape" - label="Eye Pop" - edit_group="shape_eyes" - edit_group_order="8" - label_min="Pop Right Eye" - label_max="Pop Left Eye" - value_min="-2" - value_max="2" - value_default="0" - camera_distance=".5" - camera_elevation=".04" - camera_angle="-20"> - <param_morph /> + wearable="skin" + edit_group="skin_makeup" + edit_group_order="15" + name="Nail Polish" + label_min="No Polish" + label_max="Painted Nails" + value_min="0" + value_max="1" + value_default="0.0" + camera_distance="1.6" + camera_elevation="-.4" + camera_angle="70"> + <param_alpha + tga_file="nailpolish_alpha.tga" + skip_if_zero="true" + domain="0.1" /> </param> <param - shared="1" - id="21" + id="715" group="0" - name="Upper_Eyelid_Fold" - label="Upper Eyelid Fold" - wearable="shape" - edit_group="shape_eyes" - label_min="Uncreased" - label_max="Creased" - value_min="-0.2" - value_max="1.3" - camera_elevation=".1" - camera_distance=".35"> - <param_morph /> - </param> + wearable="skin" + edit_group="skin_makeup" + edit_group_order="16" + name="Nail Polish Color" + label_min="Pink" + label_max="Black" + value_min="0" + value_max="1" + camera_distance="1.6" + camera_elevation="-.4" + camera_angle="70"> + <param_color> + <value + color="255,187,200,255" /> - <param - shared="1" - id="24" - group="0" - name="Wide_Eyes" - label="Eye Opening" - wearable="shape" - edit_group="shape_eyes" - label_min="Narrow" - label_max="Wide" - show_simple="true" - value_min="-1.5" - value_max="2" - camera_elevation=".1" - camera_distance=".3"> - <param_morph /> + <value + color="194,102,127,255" /> + + <value + color="227,34,99,255" /> + + <value + color="168,41,60,255" /> + + <value + color="97,28,59,255" /> + + <value + color="234,115,93,255" /> + + <value + color="142,58,47,255" /> + + <value + color="114,30,46,255" /> + + <value + color="14,14,14,255" /> + </param_color> </param> + </layer> + + <layer + name="upper_gloves bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="upper_gloves" + local_texture_alpha_only="true" /> <param - shared="1" - id="186" + id="1059" group="1" - name="Egg_Head" - label="Egg Head" - wearable="shape" - edit_group="shape_head" - label_min="Chin Heavy" - label_max="Forehead Heavy" - value_min="-1.3" + wearable="gloves" + edit_group="driven" + name="Glove Length bump" + value_min=".01" value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> + value_default=".8"> + <param_alpha + tga_file="glove_length_alpha.tga" + domain="0.01" /> </param> <param - shared="1" - id="187" + id="1061" group="1" - name="Squash_Stretch_Head" - label="Squash/Stretch Head" - wearable="shape" - edit_group="shape_head" - label_min="Squash Head" - label_max="Stretch Head" - value_min="-.5" + wearable="gloves" + edit_group="driven" + name="Glove Fingers bump" + value_min=".01" value_max="1" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_morph /> + value_default="1"> + <param_alpha + tga_file="gloves_fingers_alpha.tga" + multiply_blend="true" + domain="0.01" /> </param> + </layer> - <param - shared="1" - id="194" - group="1" - name="Eye_Spread" - edit_group="shape_eyes" - label_min="Eyes Together" - label_max="Eyes Spread" - value_min="-2" - value_max="2"> - <param_morph /> - </param> + <layer + name="upper_gloves"> + <texture + local_texture="upper_gloves" /> <param - id="518" + id="827" group="0" - name="Eyelashes_Long" - wearable="shape" - label="Eyelash Length" - edit_group="shape_eyes" - edit_group_order="7" - label_min="Short" - label_max="Long" - value_min="-.3" - value_max="1.5" - camera_elevation=".1" - camera_distance=".30" - camera_angle="-20"> - <param_morph /> + wearable="gloves" + edit_group="colorpicker" + name="gloves_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> </param> <param - shared="1" - id="650" + id="829" group="0" - name="Eyelid_Corner_Up" - label="Outer Eye Corner" - wearable="shape" - edit_group="shape_eyes" - label_min="Corner Down" - label_max="Corner Up" - value_min="-1.3" - value_max="1.2" - camera_elevation=".1" - camera_distance=".3"> - <param_morph /> + wearable="gloves" + edit_group="colorpicker" + name="gloves_green" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> </param> - + <param - shared="1" - id="880" + id="830" group="0" - name="Eyelid_Inner_Corner_Up" - label="Inner Eye Corner" - wearable="shape" - edit_group="shape_eyes" - label_min="Corner Down" - label_max="Corner Up" - value_min="-1.3" - value_max="1.2" - camera_elevation=".1" - camera_distance=".3"> - <param_morph /> - </param> + wearable="gloves" + edit_group="colorpicker" + name="gloves_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - <param - shared="1" - id="686" - group="1" - name="Head_Eyes_Big" - wearable="shape" - label="Eye Size" - edit_group="shape_eyes" - label_min="Beady Eyes" - label_max="Anime Eyes" - value_min="-2" - value_max="2" - show_simple="true" - value_default="0"> - <param_morph /> + <value + color="0, 0, 255, 255" /> + </param_color> </param> <param - shared="1" - id="767" + id="1058" group="1" - name="Bug_Eyed_Head" - wearable="shape" - label="Eye Depth" - edit_group="shape_eyes" - edit_group_order="4.5" - label_min="Sunken Eyes" - label_max="Bug Eyes" - value_min="-2" - value_max="2" - value_default="0"> - <param_morph /> + wearable="gloves" + edit_group="driven" + name="Glove Length" + value_min=".01" + value_max="1" + value_default=".8"> + <param_alpha + tga_file="glove_length_alpha.tga" + domain="0.01" /> </param> -<!-- - ############## - # Facial Expression morphs - ############## - --> <param - shared="1" - id="301" + id="1060" group="1" - name="Express_Tongue_Out" - value_min="0" - value_max="1"> - <param_morph /> + wearable="gloves" + edit_group="driven" + name="Glove Fingers" + value_min=".01" + value_max="1" + value_default="1"> + <param_alpha + tga_file="gloves_fingers_alpha.tga" + multiply_blend="true" + domain="0.01" /> </param> + </layer> - <param - shared="1" - id="302" - group="1" - name="Express_Surprise_Emote" - value_min="0" - value_max="1"> - <param_morph /> - </param> + <layer + name="upper_clothes_shadow"> + <texture + local_texture="upper_shirt" /> <param - shared="1" - id="303" + id="899" group="1" - name="Express_Wink_Emote" + edit_group="driven" + wearable="shirt" + name="Upper Clothes Shading" value_min="0" - value_max="1"> - <param_morph /> - </param> + value_max="1" + value_default="0"> + <param_color> + <value + color="0, 0, 0, 0" /> - <param - shared="1" - id="304" - group="1" - name="Express_Embarrassed_Emote" - value_min="0" - value_max="1"> - <param_morph /> + <value + color="0, 0, 0, 80" /> + </param_color> </param> <param - shared="1" - id="305" + id="900" group="1" - name="Express_Shrug_Emote" - value_min="0" - value_max="1"> - <param_morph /> + wearable="shirt" + edit_group="driven" + name="Sleeve Length Shadow" + value_min="0.02" + value_max=".87" + value_default="0.02"> + <param_alpha + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" + skip_if_zero="true" + domain="0.03" /> </param> <param - shared="1" - id="306" + id="901" group="1" - name="Express_Kiss" - value_min="0" + wearable="shirt" + edit_group="driven" + name="Shirt Shadow Bottom" + value_min="0.02" value_max="1"> - <param_morph /> + <param_alpha + multiply_blend="true" + tga_file="shirt_bottom_alpha.tga" + skip_if_zero="true" + domain="0.05" /> </param> <param - shared="1" - id="307" + id="902" group="1" - name="Express_Bored_Emote" - value_min="0" + wearable="shirt" + edit_group="driven" + name="Collar Front Shadow Height" + value_min="0.02" value_max="1"> - <param_morph /> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_alpha.tga" + skip_if_zero="true" + domain="0.02" /> </param> <param - shared="1" - id="308" + id="903" group="1" - name="Express_Repulsed_Emote" - value_min="0" + wearable="shirt" + edit_group="driven" + name="Collar Back Shadow Height" + value_min="0.02" value_max="1"> - <param_morph /> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_back_alpha.tga" + skip_if_zero="true" + domain="0.02" /> </param> + </layer> - <param - shared="1" - id="309" - group="1" - name="Express_Disdain" - value_min="0" - value_max="1"> - <param_morph /> - </param> + <layer + name="upper_shirt base bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="upper_shirt" + local_texture_alpha_only="true" /> <param - shared="1" - id="310" + id="1029" group="1" - name="Express_Afraid_Emote" + wearable="shirt" + edit_group="driven" + name="Sleeve Length Cloth" value_min="0" - value_max="1"> - <param_morph /> + value_max="0.85"> + <param_alpha + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" + domain="0.01" /> </param> <param - shared="1" - id="312" + id="1030" group="1" - name="Express_Cry_Emote" + wearable="shirt" + edit_group="driven" + name="Shirt Bottom Cloth" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + multiply_blend="true" + tga_file="shirt_bottom_alpha.tga" + domain="0.05" /> </param> <param - shared="1" - id="313" + id="1031" group="1" - name="Express_Sad_Emote" + wearable="shirt" + edit_group="driven" + name="Collar Front Height Cloth" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_alpha.tga" + domain="0.05" /> </param> <param - shared="1" - id="314" + id="1032" group="1" - name="Express_Anger_Emote" + wearable="shirt" + edit_group="driven" + name="Collar Back Height Cloth" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_back_alpha.tga" + domain="0.05" /> </param> + </layer> - <param - shared="1" - id="315" - group="1" - name="Express_Frown" - value_min="0" - value_max="1"> - <param_morph /> - </param> + <layer + name="upper_clothes bump" + render_pass="bump"> + <texture + tga_file="bump_shirt_wrinkles.tga" /> - <param - shared="1" - id="316" - group="1" - name="Express_Laugh_Emote" - value_min="0" - value_max="1"> - <param_morph /> - </param> + <texture + local_texture="upper_shirt" + local_texture_alpha_only="true" /> <param - shared="1" - id="317" - group="1" - name="Express_Toothsmile" + id="868" + group="0" + wearable="shirt" + edit_group="shirt" + edit_group_order="8" + name="Shirt Wrinkles" value_min="0" - value_max="1"> - <param_morph /> + value_max="1" + value_default="0"> + <param_color> + <value + color="255, 255, 255, 0" /> + + <value + color="255, 255, 255, 255" /> + </param_color> </param> <param - shared="1" - id="318" + id="1013" group="1" - name="Express_Smile" + wearable="shirt" + edit_group="driven" + name="Sleeve Length Cloth" value_min="0" - value_max="1"> - <param_morph /> + value_max="0.85"> + <param_alpha + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" + domain="0.01" /> </param> -<!-- - ############## - # other morphs (not user controlled) - ############## - --> <param - shared="1" - id="41" + id="1014" group="1" - name="Old" + wearable="shirt" + edit_group="driven" + name="Shirt Bottom Cloth" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + multiply_blend="true" + tga_file="shirt_bottom_alpha.tga" + domain="0.05" /> </param> -<!-- - ############## - # animatable morphs - ############## - --> <param - shared="1" - id="58" + id="1015" group="1" - name="Blink_Left" + wearable="shirt" + edit_group="driven" + name="Collar Front Height Cloth" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_alpha.tga" + domain="0.05" /> </param> <param - shared="1" - id="59" + id="1016" group="1" - name="Blink_Right" - value_min="0" - value_max="1"> - <param_morph /> - </param> - </mesh> - -<!-- - #headMesh2 = - #headMesh3 = - --> - <mesh - type="upperBodyMesh" - lod="0" - file_name="avatar_upper_body.llm" - min_pixel_width="320"> -<!-- - #begin morph targets - ############# - # tweakable morphs - ############# - --> - <param - id="104" - group="1" - name="Big_Belly_Torso" + wearable="shirt" + edit_group="driven" + name="Collar Back Height Cloth" value_min="0" value_max="1"> - <param_morph> - <volume_morph - name="BELLY" - scale="0.075 0.04 0.03" - pos="0.07 0 -0.07"/> - </param_morph> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_back_alpha.tga" + domain="0.05" /> </param> + </layer> + + <layer + name="upper_clothes"> + <texture + local_texture="upper_shirt" /> <param - id="626" - sex="female" - group="1" - name="Big_Chest" - label="Chest Size" - wearable="shape" - edit_group="shape_torso" - label_min="Small" - label_max="Large" + id="803" + group="0" + wearable="shirt" + edit_group="colorpicker" + name="shirt_red" value_min="0" value_max="1" - camera_elevation=".1" - camera_distance="1" - camera_angle="15"> - <param_morph /> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> </param> <param - id="627" - sex="female" - group="1" - name="Small_Chest" - label="Chest Size" - wearable="shape" - edit_group="shape_torso" - label_min="Large" - label_max="Small" + id="804" + group="0" + wearable="shirt" + edit_group="colorpicker" + name="shirt_green" value_min="0" value_max="1" - camera_elevation="0" - camera_distance=".28"> - <param_morph /> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> </param> <param - id="843" - sex="female" - group="1" - name="No_Chest" - label="Chest Size" - wearable="shape" - edit_group="shape_torso" - label_min="Some" - label_max="None" + id="805" + group="0" + wearable="shirt" + edit_group="colorpicker" + name="shirt_blue" value_min="0" value_max="1" - camera_elevation="0" - camera_distance=".28"> - <param_morph /> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> </param> <param - id="106" - group="1" - name="Muscular_Torso" - label="Torso Muscles" - show_simple="true" - wearable="shape" - edit_group="shape_torso" - label_min="Regular" - label_max="Muscular" - value_min="0" - value_max="1.4" - camera_elevation=".3" - camera_distance="1.2"> - <param_morph> - <volume_morph - name="L_CLAVICLE" - scale="0.02 0.0 0.005" - pos="0.0 0 0.005"/> - <volume_morph - name="L_UPPER_ARM" - scale="0.015 0.0 0.005" - pos="0.015 0 0"/> - <volume_morph - name="L_LOWER_ARM" - scale="0.005 0.0 0.005" - pos="0.005 0 0"/> - <volume_morph - name="R_CLAVICLE" - scale="0.02 0.0 0.005" - pos="0.0 0 0.005"/> - <volume_morph - name="R_UPPER_ARM" - scale="0.015 0.0 0.005" - pos="0.015 0 0"/> - <volume_morph - name="R_LOWER_ARM" - scale="0.005 0.0 0.005" - pos="0.005 0 0"/> - </param_morph> - </param> - - <param - id="648" - group="1" - sex="female" - name="Scrawny_Torso" - label="Torso Muscles" - show_simple="true" - wearable="shape" - edit_group="shape_torso" - label_min="Regular" - label_max="Scrawny" - value_min="0" - value_max="1.3" - camera_elevation=".3" - camera_distance="1.2"> - <param_morph> - <volume_morph - name="BELLY" - scale="0.0 -0.01 0.0" - pos="0.0 0.0 0"/> - <volume_morph - name="CHEST" - scale="-0.01 -0.01 0.0" - pos="0.01 0.0 0"/> - <volume_morph - name="L_CLAVICLE" - scale="0.0 -0.03 -0.005" - pos="0.0 0 -0.005"/> - <volume_morph - name="L_UPPER_ARM" - scale="-0.01 -0.01 -0.02" - pos="0 0 0"/> - <volume_morph - name="L_LOWER_ARM" - scale="-0.005 0.0 -0.01" - pos="-0.005 0 0"/> - <volume_morph - name="R_CLAVICLE" - scale="0.0 -0.03 -0.005" - pos="0.0 0 -0.005"/> - <volume_morph - name="R_UPPER_ARM" - scale="-0.01 -0.01 -0.02" - pos="0 0 0"/> - <volume_morph - name="R_LOWER_ARM" - scale="-0.005 0.0 -0.01" - pos="-0.005 0 0"/> - </param_morph> - </param> - - <param - id="677" + id="600" group="1" - sex="male" - name="Scrawny_Torso_Male" - label="Torso Scrawny" - wearable="shape" - edit_group="shape_torso" - label_min="Regular" - label_max="Scrawny" - value_min="0" - value_max="1.3" - camera_elevation=".3" - camera_distance="1.2"> - <param_morph> - <volume_morph - name="BELLY" - scale="-0.01 -0.01 0.0" - pos="0.01 0.0 0"/> - <volume_morph - name="CHEST" - scale="-0.02 -0.02 0.0" - pos="0.01 0.0 0"/> - <volume_morph - name="L_CLAVICLE" - scale="0.0 -0.03 -0.005" - pos="0.0 0 -0.005"/> - <volume_morph - name="L_UPPER_ARM" - scale="-0.01 -0.01 -0.02" - pos="0 0 0"/> - <volume_morph - name="L_LOWER_ARM" - scale="-0.005 0.0 -0.01" - pos="-0.005 0 0"/> - <volume_morph - name="R_CLAVICLE" - scale="0.0 -0.03 -0.005" - pos="0.0 0 -0.005"/> - <volume_morph - name="R_UPPER_ARM" - scale="-0.01 -0.01 -0.02" - pos="0 0 0"/> - <volume_morph - name="R_LOWER_ARM" - scale="-0.005 0.0 -0.01" - pos="-0.005 0 0"/> - </param_morph> - </param> - - <param - id="634" - group="1" - name="Fat_Torso" - label="Fat Torso" - wearable="shape" - edit_group="shape_body" - label_min="skinny" - label_max="fat" + wearable="shirt" + edit_group="driven" + name="Sleeve Length Cloth" value_min="0" - value_max="1" - camera_elevation=".3"> - <param_morph> - <volume_morph - name="CHEST" - scale="0.02 0.03 0.03" - pos="0 0 -0.03"/> - <volume_morph - name="BELLY" - scale="0.09 0.08 0.07" - pos="0 0 -0.05"/> - <volume_morph - name="L_CLAVICLE" - scale="0.0 0.0 0.015"/> - <volume_morph - name="L_UPPER_ARM" - scale="0.02 0.0 0.02" - pos="0.0 0.0 -0.02"/> - <volume_morph - name="L_LOWER_ARM" - scale="0.01 0.0 0.01" - pos="0.0 0.0 -0.01"/> - <volume_morph - name="R_CLAVICLE" - scale="0.0 0.0 0.015"/> - <volume_morph - name="R_UPPER_ARM" - scale="0.02 0.0 0.02" - pos="0.0 0.0 -0.02"/> - <volume_morph - name="R_LOWER_ARM" - scale="0.01 0.0 0.01" - pos="0.0 0.0 -0.01"/> - <volume_morph - name="NECK" - scale="0.015 0.01 0.0"/> - <volume_morph - name="HEAD" - scale="0.0 0.0 0.01" - pos="0 0 -0.01"/> - </param_morph> - - </param> - - <param - id="507" - group="0" - sex="female" - name="Breast_Gravity" - label="Breast Buoyancy" - wearable="shape" - edit_group="shape_torso" - edit_group_order="7" - label_min="Less Gravity" - label_max="More Gravity" - value_default="0" - value_min="-1.5" - value_max="2" - camera_elevation=".3" - camera_distance=".8"> - <param_morph /> + value_max="0.85" + value_default=".7"> + <param_alpha + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" + domain="0.01" /> </param> <param - id="628" + id="601" group="1" - name="Displace_Loose_Upperbody" - label="Shirt Fit" wearable="shirt" edit_group="driven" - clothing_morph="true" + name="Shirt Bottom Cloth" value_min="0" value_max="1" - value_default="0"> - <param_morph /> + value_default=".8"> + <param_alpha + multiply_blend="true" + tga_file="shirt_bottom_alpha.tga" + domain="0.05" /> </param> <param - id="840" - group="0" - name="Shirtsleeve_flair" - label="Sleeve Looseness" - show_simple="true" + id="602" + group="1" wearable="shirt" - edit_group="shirt" - edit_group_order="6" - clothing_morph="true" - label_min="Tight Sleeves" - label_max="Loose Sleeves" + edit_group="driven" + name="Collar Front Height Cloth" value_min="0" - value_max="1.5" - camera_distance="1.8" - camera_angle="30" - camera_elevation="-.3"> - <param_morph /> + value_max="1" + value_default=".8"> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_alpha.tga" + domain="0.05" /> </param> <param - id="855" + id="778" group="1" - name="Love_Handles" - value_default="0" - value_min="-1" - value_max="2"> - <param_morph> - <volume_morph - name="BELLY" - scale="0.0 0.02 0.0"/> - </param_morph> - </param> - - <param - id="684" - group="0" - sex="female" - name="Breast_Female_Cleavage" - label="Breast Cleavage" - wearable="shape" - edit_group="shape_torso" - edit_group_order="8" - label_min="Separate" - label_max="Join" - value_default="0" - value_min="-.3" - value_max="1.3" - camera_elevation=".3" - camera_distance=".8"> - <param_morph /> + wearable="shirt" + edit_group="driven" + name="Collar Back Height Cloth" + value_min="0" + value_max="1" + value_default=".8"> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_back_alpha.tga" + domain="0.05" /> </param> + </layer> - <param - id="685" - group="0" - sex="male" - name="Chest_Male_No_Pecs" - label="Pectorals" - wearable="shape" - edit_group="shape_torso" - edit_group_order="5" - label_min="Big Pectorals" - label_max="Sunken Chest" - value_default="0" - value_min="-.5" - value_max="1.1" - camera_elevation=".3" - camera_distance="1.2"> - <param_morph /> - </param> + <layer + name="upper_jacket base bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="upper_jacket" + local_texture_alpha_only="true" /> -<!-- ############# # - other morphs (not user controlled) - ############# --> <param - id="100" + id="1039" group="1" - name="Male_Torso" - label_min="Male_Torso" - value_min="0" - value_max="1"> - <param_morph> - <volume_morph - name="CHEST" - scale="0.03 0.04 0.02" - pos="-0.03 0 -0.01"/> - <volume_morph - name="BELLY" - scale="0.03 0.03 0.0" - pos="-0.03 0 0.02"/> - <volume_morph - name="L_CLAVICLE" - scale="0.02 0.0 0.01" - pos="-0.02 0 0"/> - <volume_morph - name="L_UPPER_ARM" - scale="0.01 0.0 0.01" - pos="0.0 0.0 -0.01"/> - <volume_morph - name="L_LOWER_ARM" - scale="0.005 0.0 0.005" - pos="0.0 0.0 -0.005"/> - <volume_morph - name="R_CLAVICLE" - scale="0.02 0.0 0.01" - pos="-0.02 0 0"/> - <volume_morph - name="R_UPPER_ARM" - scale="0.01 0.0 0.01" - pos="0.0 0.0 -0.01"/> - <volume_morph - name="R_LOWER_ARM" - scale="0.005 0.0 0.005" - pos="0.0 0.0 -0.005"/> - <volume_morph - name="NECK" - scale="0.015 0.01 0.0"/> - <volume_morph - name="HEAD" - scale="0.0 0.0 0.01" - pos="0 0 -0.01"/> - </param_morph> - </param> - -<!-- - ############## - # animatable morphs - ############## - --> - <param - id="101" - group="1" - name="Hands_Relaxed" + wearable="jacket" + edit_group="driven" + edit_group_order="1" + name="Jacket Sleeve Length bump" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" + domain="0.01" /> </param> <param - id="102" + id="1040" group="1" - name="Hands_Point" + wearable="jacket" + edit_group="driven" + name="Jacket Collar Front bump" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_alpha.tga" + domain="0.05" /> </param> <param - id="103" + id="1041" group="1" - name="Hands_Fist" + wearable="jacket" + edit_group="driven" + edit_group_order="3.5" + name="Jacket Collar Back bump" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_back_alpha.tga" + domain="0.05" /> </param> <param - id="666" + id="1037" group="1" - name="Hands_Relaxed_L" + wearable="jacket" + edit_group="driven" + name="jacket bottom length upper bump" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + multiply_blend="true" + tga_file="jacket_length_upper_alpha.tga" + domain="0.01" /> </param> <param - id="667" + id="1038" group="1" - name="Hands_Point_L" + wearable="jacket" + edit_group="driven" + name="jacket open upper bump" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + multiply_blend="true" + tga_file="jacket_open_upper_alpha.tga" + domain="0.01" /> </param> + </layer> - <param - id="668" - group="1" - name="Hands_Fist_L" - value_min="0" - value_max="1"> - <param_morph /> - </param> + <layer + name="upper_jacket bump" + render_pass="bump"> + <texture + tga_file="bump_shirt_wrinkles.tga" /> - <param - id="669" - group="1" - name="Hands_Relaxed_R" - value_min="0" - value_max="1"> - <param_morph /> - </param> + <texture + local_texture="upper_jacket" + local_texture_alpha_only="true" /> + <param - id="670" - group="1" - name="Hands_Point_R" - value_min="0" - value_max="1"> - <param_morph /> + id="875" + group="1" + wearable="jacket" + name="jacket upper Wrinkles" + value_min="0" + value_max="1" + value_default="0"> + <param_color> + <value + color="255, 255, 255, 0" /> + + <value + color="255, 255, 255, 255" /> + </param_color> </param> <param - id="671" + id="1019" group="1" - name="Hands_Fist_R" + wearable="jacket" + edit_group="driven" + edit_group_order="1" + name="Jacket Sleeve Length bump" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" + domain="0.01" /> </param> <param - id="672" + id="1021" group="1" - name="Hands_Typing" + wearable="jacket" + edit_group="driven" + name="Jacket Collar Front bump" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_alpha.tga" + domain="0.05" /> </param> <param - id="766" + id="1023" group="1" - name="Hands_Salute_R" + wearable="jacket" + edit_group="driven" + edit_group_order="3.5" + name="Jacket Collar Back bump" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_back_alpha.tga" + domain="0.05" /> </param> <param - id="791" + id="1025" group="1" - name="Hands_Peace_R" + wearable="jacket" + edit_group="driven" + name="jacket bottom length upper bump" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + multiply_blend="true" + tga_file="jacket_length_upper_alpha.tga" + domain="0.01" /> </param> <param - id="792" + id="1026" group="1" - name="Hands_Spread_R" + wearable="jacket" + edit_group="driven" + name="jacket open upper bump" value_min="0" value_max="1"> - <param_morph /> + <param_alpha + multiply_blend="true" + tga_file="jacket_open_upper_alpha.tga" + domain="0.01" /> </param> + </layer> -<!-- - #end morph targets - --> - </mesh> - - <mesh - type="upperBodyMesh" - lod="1" - file_name="avatar_upper_body_1.llm" - min_pixel_width="160" - reference="avatar_upper_body.llm"> - </mesh> - - <mesh - type="upperBodyMesh" - lod="2" - file_name="avatar_upper_body_2.llm" - min_pixel_width="80" - reference="avatar_upper_body.llm"> - </mesh> - - <mesh - type="upperBodyMesh" - lod="3" - file_name="avatar_upper_body_3.llm" - min_pixel_width="40" - reference="avatar_upper_body.llm"> - </mesh> - - <mesh - type="upperBodyMesh" - lod="4" - file_name="avatar_upper_body_4.llm" - min_pixel_width="0" - reference="avatar_upper_body.llm"> - </mesh> - -<!-- - #upperBodyMesh2 = - #upperBodyMesh3 = - --> - <mesh - type="lowerBodyMesh" - lod="0" - file_name="avatar_lower_body.llm" - min_pixel_width="320"> -<!-- - #begin morph targets - ############# - # tweakable morphs - ############# - --> - <param - id="156" - group="1" - name="Big_Belly_Legs" - value_min="0" - value_max="1"> - <param_morph /> - </param> + <layer + name="upper_jacket"> + <texture + local_texture="upper_jacket" /> <param - id="151" + id="831" group="1" - name="Big_Butt_Legs" - label="Butt Size" - wearable="shape" - edit_group="shape_legs" - label_min="Regular" - label_max="Large" + edit_group="colorpicker_driven" + wearable="jacket" + name="upper_jacket_red" value_min="0" - value_max="1"> - <param_morph> - <volume_morph - name="PELVIS" - scale="0.03 0.0 0.02" - pos="-0.03 0 -0.025"/> - </param_morph> - </param> + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - <param - id="794" - group="1" - name="Small_Butt" - label="Butt Size" - wearable="shape" - edit_group="shape_legs" - label_min="Regular" - label_max="Small" - value_min="0" - value_max="1"> - <param_morph> - <volume_morph - name="PELVIS" - scale="-0.01 0.0 0.0" - pos="0.01 0 0.0"/> - </param_morph> + <value + color="255, 0, 0, 255" /> + </param_color> </param> <param - id="152" - group="1" - name="Muscular_Legs" - label="Leg Muscles" - show_simple="true" - wearable="shape" - edit_group="shape_legs" - label_min="Regular Muscles" - label_max="More Muscles" - value_min="0" - value_max="1.5" - camera_distance="1.3" - camera_elevation="-.5"> - <param_morph> - <volume_morph - name="L_UPPER_LEG" - scale="0.015 0.015 0.0" - pos="0.0 0 0.0"/> - <volume_morph - name="L_LOWER_LEG" - scale="0.01 0.01 0.0" - pos="0.0 0 0.0"/> - <volume_morph - name="R_UPPER_LEG" - scale="0.015 0.015 0.0" - pos="0.0 0 0.0"/> - <volume_morph - name="R_LOWER_LEG" - scale="0.01 0.01 0.0" - pos="0.0 0 0.0"/> - </param_morph> - </param> - - <param - id="651" - group="1" - name="Scrawny_Legs" - label="Scrawny Leg" - wearable="shape" - edit_group="shape_legs" - label_min="Regular Muscles" - label_max="Less Muscles" - value_min="0" - value_max="1.5" - camera_distance="1.3" - camera_elevation="-.5"> - <param_morph> - <volume_morph - name="L_UPPER_LEG" - scale="-0.03 -0.03 0.0" - pos="0.0 0 0.0"/> - <volume_morph - name="L_LOWER_LEG" - scale="-0.015 -0.015 0.0" - pos="0.0 0 0.0"/> - <volume_morph - name="R_UPPER_LEG" - scale="-0.03 -0.03 0.0" - pos="0.0 0 0.0"/> - <volume_morph - name="R_LOWER_LEG" - scale="-0.015 -0.015 0.0" - pos="0.0 0 0.0"/> - </param_morph> - </param> - - <param - id="853" - group="1" - name="Bowed_Legs" - label="Knee Angle" - wearable="shape" - value_min="-1" - value_max="1"> - <param_morph> - <volume_morph - name="L_UPPER_LEG" - pos="0.0 0.03 0.0"/> - <volume_morph - name="L_LOWER_LEG" - pos="0.0 0.03 0.0"/> - <volume_morph - name="R_UPPER_LEG" - pos="0.0 -0.03 0.0"/> - <volume_morph - name="R_LOWER_LEG" - pos="0.0 -0.03 0.0"/> - </param_morph> - </param> - - <param - id="500" + id="832" group="1" - name="Shoe_Heel_Height" - label="Heel Height" - wearable="shoes" - edit_group="shoes" - label_min="Low Heels" - label_max="High Heels" + edit_group="colorpicker_driven" + wearable="jacket" + name="upper_jacket_green" value_min="0" value_max="1" - camera_distance="1.5" - camera_elevation="-.5"> - <param_morph /> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> </param> <param - id="501" + id="833" group="1" - name="Shoe_Platform_Height" - label="Platform Height" - wearable="shoes" - edit_group="shoes" - label_min="Low Platforms" - label_max="High Platforms" + edit_group="colorpicker_driven" + wearable="jacket" + name="upper_jacket_blue" value_min="0" value_max="1" - camera_distance="1.5" - camera_elevation="-.5"> - <param_morph /> - </param> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - <param - id="508" - group="0" - name="Shoe_Platform_Width" - label="Platform Width" - wearable="shoes" - edit_group="shoes" - edit_group_order="7" - label_min="Narrow" - label_max="Wide" - value_min="-1" - value_max="2" - camera_angle="15" - camera_distance="1.5" - camera_elevation="-1"> - <param_morph /> + <value + color="0, 0, 255, 255" /> + </param_color> </param> <param - id="509" + id="1020" group="1" - name="Shoe_Heel_Point" - label="Heel Shape" - wearable="shoes" - edit_group="shoes" - label_min="Default Heels" - label_max="Pointy Heels" - value_min="0" - value_max="1" - camera_distance="1.3" - camera_elevation="-.5"> - <param_morph /> + edit_group="driven" + wearable="jacket" + name="jacket Sleeve Length" value_min="0" + value_max="1"> + <param_alpha + multiply_blend="false" + tga_file="shirt_sleeve_alpha.tga" + domain="0.01" /> </param> <param - id="510" + id="1022" group="1" - name="Shoe_Heel_Thick" - label="Heel Shape" - wearable="shoes" - edit_group="shoes" - label_min="default Heels" - label_max="Thick Heels" + wearable="jacket" + edit_group="driven" + name="jacket Collar Front" value_min="0" - value_max="1" - camera_distance="1.3" - camera_elevation="-.5"> - <param_morph /> + value_max="1"> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_alpha.tga" + domain="0.05" /> </param> <param - id="511" + id="1024" group="1" - name="Shoe_Toe_Point" - label="Toe Shape" - wearable="shoes" - edit_group="shoes" - label_min="Default Toe" - label_max="Pointy Toe" + wearable="jacket" + edit_group="driven" + edit_group_order="3.5" + name="jacket Collar Back" value_min="0" - value_max="1" - camera_distance="1.3" - camera_elevation="-.5"> - <param_morph /> + value_max="1"> + <param_alpha + multiply_blend="true" + tga_file="shirt_collar_back_alpha.tga" + domain="0.05" /> </param> <param - id="512" + id="620" group="1" - name="Shoe_Toe_Square" - label="Toe Shape" - wearable="shoes" - edit_group="shoes" - label_min="Default Toe" - label_max="Square Toe" + wearable="jacket" + edit_group="jacket" + name="bottom length upper" + label_min="hi cut" + label_max="low cut" value_min="0" value_max="1" - camera_distance="1.5" - camera_elevation="-.5"> - <param_morph /> - </param> - - <param - id="654" - group="0" - name="Shoe_Toe_Thick" - label="Toe Thickness" - wearable="shoes" - edit_group="shoes" - edit_group_order="5" - label_min="Flat Toe" - label_max="Thick Toe" - value_min="0" - value_max="2" - camera_angle="15" - camera_distance="1.5" - camera_elevation="-1"> - <param_morph /> + value_default=".8" + camera_distance="1.2" + camera_angle="30" + camera_elevation=".2"> + <param_alpha + multiply_blend="true" + tga_file="jacket_length_upper_alpha.tga" + domain="0.01" /> </param> <param - id="515" - group="0" - name="Foot_Size" - label="Foot Size" - wearable="shape" - edit_group="shape_legs" - edit_group_order="6" - label_min="Small" - label_max="Big" - value_min="-1" - value_max="3" - camera_angle="45" - camera_distance="1.1" - camera_elevation="-1"> - <param_morph> - <volume_morph - name="L_FOOT" - scale="0.02 0.01 0.0" - pos="0.01 0 0"/> - <volume_morph - name="R_FOOT" - scale="0.02 0.01 0.0" - pos="0.01 0 0"/> - </param_morph> - </param> - - <param - id="516" + id="622" group="1" - name="Displace_Loose_Lowerbody" - label="Pants Fit" - wearable="pants" - edit_group="driven" - clothing_morph="true" + wearable="jacket" + edit_group="jacket" + name="open upper" + label_min="closed" + label_max="open" value_min="0" value_max="1" - value_default="0"> - <param_morph /> - </param> - - <param - id="625" - group="0" - name="Leg_Pantflair" - label="Cuff Flare" - show_simple="true" - wearable="pants" - edit_group="pants" - edit_group_order="3" - clothing_morph="true" - label_min="Tight Cuffs" - label_max="Flared Cuffs" - value_min="0" - value_max="1.5" - camera_distance="1.8" + value_default=".8" + camera_distance="1.2" camera_angle="30" - camera_elevation="-.3"> - <param_morph /> + camera_elevation=".2"> + <param_alpha + multiply_blend="true" + tga_file="jacket_open_upper_alpha.tga" + domain="0.01" /> </param> + </layer> + + <layer + name="upper alpha" + visibility_mask="TRUE"> + <texture + local_texture="upper_alpha" /> + </layer> + + </layer_set> + + <!-- =========================================================== --> + <layer_set + body_region="lower_body" + width="512" + height="512"> + <layer + name="lower body bump base" + fixed_color = "128,128,128,255" + render_pass="bump"> + </layer> + <layer + name="base_lowerbody bump" + render_pass="bump"> + <texture + tga_file="bump_lowerbody_base.tga" + file_is_mask="FALSE" /> <param - id="793" + id="878" group="1" - name="Leg_Longcuffs" - label="Longcuffs" - wearable="pants" + wearable="skin" edit_group="driven" - clothing_morph="true" + edit_group_order="20" + name="Bump upperdef" value_min="0" - value_max="3" - value_default="0"> - <param_morph /> + value_max="1"> + <param_alpha + domain="0" /> </param> + </layer> - <param - id="638" - group="0" - name="Low_Crotch" - label="Pants Crotch" - wearable="pants" - clothing_morph="true" - edit_group="pants" - edit_group_order="4" - label_min="High and Tight" - label_max="Low and Loose" - value_min="0" - value_max="1.3" - camera_distance="1.2" - camera_angle="-20" - camera_elevation="-.3"> - <param_morph /> - </param> + <layer + name="base" + global_color="skin_color"> + <texture + tga_file="body_skingrain.tga" /> + </layer> + + <layer + name="shadow"> + <texture + tga_file="lowerbody_shading_alpha.tga" + file_is_mask="TRUE" /> <param - id="635" + id="160" group="1" - name="Fat_Legs" - label="Fat Torso" - wearable="shape" - edit_group="shape_body" - label_min="skinny" - label_max="fat" + name="Shading" + wearable="pants" + cross_wearable="true" value_min="0" value_max="1"> - <param_morph> - <volume_morph - name="PELVIS" - scale="0.03 0.06 0.0"/> - <volume_morph - name="R_UPPER_LEG" - scale="0.02 0.02 0.0" - pos="0.0 -0.02 0.0"/> - <volume_morph - name="R_LOWER_LEG" - scale="0.01 0.01 0.0"/> - <volume_morph - name="L_UPPER_LEG" - scale="0.02 0.02 0.0" - pos="0.0 0.02 0.0"/> - <volume_morph - name="L_LOWER_LEG" - scale="0.01 0.01 0.0"/> - </param_morph> - </param> - - <param - id="854" - group="1" - name="Saddlebags" - value_min="-.5" - value_max="3"> - <param_morph> - <volume_morph - name="PELVIS" - scale="0.0 0.025 0.0"/> - </param_morph> + <param_color> + <value + color="0, 0, 0, 0" /> + <value + color="0, 0, 0, 128" /> + </param_color> </param> + </layer> - <param - id="879" - group="0" - sex="male" - name="Male_Package" - label="Package" - wearable="shape" - edit_group="shape_legs" - edit_group_order="4.6" - label_min="Coin Purse" - label_max="Duffle Bag" - value_default="0" - value_min="-.5" - value_max="2" - camera_angle="60" - camera_distance=".6"> - <param_morph /> - </param> + <layer + name="highlight"> + <texture + tga_file="lowerbody_highlights_alpha.tga" + file_is_mask="TRUE" /> -<!-- - ############# - # other morphs (not user controlled) - ############# - --> <param - id="153" + id="161" group="1" - name="Male_Legs" + name="Shading" + wearable="skin" value_min="0" value_max="1"> - <param_morph /> - </param> - -<!-- - #end morph targets - --> - </mesh> - - <mesh - type="lowerBodyMesh" - lod="1" - file_name="avatar_lower_body_1.llm" - min_pixel_width="160" - reference="avatar_lower_body.llm"> - </mesh> - - <mesh - type="lowerBodyMesh" - lod="2" - file_name="avatar_lower_body_2.llm" - min_pixel_width="80" - reference="avatar_lower_body.llm"> - </mesh> - - <mesh - type="lowerBodyMesh" - lod="3" - file_name="avatar_lower_body_3.llm" - min_pixel_width="40" - reference="avatar_lower_body.llm"> - </mesh> - - <mesh - type="lowerBodyMesh" - lod="4" - file_name="avatar_lower_body_4.llm" - min_pixel_width="0" - reference="avatar_lower_body.llm"> - </mesh> - -<!-- - #lowerBodyMesh2 = - #lowerBodyMesh3 = - --> -<!-- - #eyeLidLeftMesh = - --> - <mesh - type="eyeBallLeftMesh" - lod="0" - file_name="avatar_eye.llm" - min_pixel_width="320"> -<!-- begin morph_params --> - <param - id="679" - group="1" - name="Eyeball_Size" - label="Eyeball Size" - wearable="shape" - edit_group="shape_eyes" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".10"> - <param_morph /> - </param> + <param_color> + <value + color="255, 255, 255, 0" /> - <param - id="687" - group="1" - name="Eyeball_Size" - label="Big Eyeball" - wearable="shape" - edit_group="shape_eyes" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".25"> - <param_morph /> - </param> - </mesh> - - <mesh - type="eyeBallLeftMesh" - lod="1" - file_name="avatar_eye_1.llm" - min_pixel_width="80"> -<!-- begin morph_params --> - <param - id="694" - group="1" - name="Eyeball_Size" - label="Eyeball Size" - wearable="shape" - edit_group="shape_eyes" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".10"> - <param_morph /> - </param> - - <param - id="695" - group="1" - name="Eyeball_Size" - label="Big Eyeball" - wearable="shape" - edit_group="shape_eyes" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".25"> - <param_morph /> - </param> - </mesh> - -<!-- - #eyeLidRightMesh = - --> - <mesh - type="eyeBallRightMesh" - lod="0" - file_name="avatar_eye.llm" - min_pixel_width="320"> -<!-- begin morph_params --> - <param - id="680" - group="1" - name="Eyeball_Size" - label="Eyeball Size" - wearable="shape" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".10"> - <param_morph /> + <value + color="255, 255, 255, 64" /> + </param_color> </param> + </layer> - <param - id="688" - group="1" - name="Eyeball_Size" - label="Big Eyeball" - wearable="shape" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".25"> - <param_morph /> - </param> - </mesh> - - <mesh - type="eyeBallRightMesh" - lod="1" - file_name="avatar_eye_1.llm" - min_pixel_width="80"> -<!-- begin morph_params --> - <param - id="681" - group="1" - name="Eyeball_Size" - label="Eyeball Size" - wearable="shape" - edit_group="shape_eyes" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".10"> - <param_morph /> - </param> + <layer + name="toenails"> + <texture + tga_file="lowerbody_color.tga" /> + </layer> - <param - id="691" - group="1" - name="Eyeball_Size" - label="Big Eyeball" - wearable="shape" - edit_group="shape_eyes" - label_min="small eye" - label_max="big eye" - value_min="-.25" - value_max=".25"> - <param_morph /> - </param> - </mesh> + <layer + name="lower_bodypaint"> + <texture + local_texture="lower_bodypaint" /> + </layer> - <mesh - type="skirtMesh" - lod="0" - file_name="avatar_skirt.llm" - min_pixel_width="320"> + <layer + name="freckles lower" + fixed_color="120,47,20,128"> <param - id="845" + id="777" group="1" - name="skirt_poofy" - label="poofy skirt" - clothing_morph="true" - wearable="skirt" - edit_group="skirt" - label_min="less poofy" - label_max="more poofy" + name="freckles lower" + wearable="skin" value_min="0" - value_max="1.5"> - <param_morph /> + value_max="1"> + <param_alpha + tga_file="bodyfreckles_alpha.tga" + skip_if_zero="true" + domain="0.6" /> </param> + </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"> + <texture + local_texture="lower_underpants" + local_texture_alpha_only="true" /> <param - id="846" + id="1055" group="1" - name="skirt_loose" - label="loose skirt" - clothing_morph="true" - wearable="skirt" - edit_group="skirt" - label_min="form fitting" - label_max="loose" + wearable="underpants" + edit_group="underpants" + name="Pants Length" value_min="0" - value_max="1"> - <param_morph /> + value_max="1" + value_default=".3"> + <param_alpha + tga_file="pants_length_alpha.tga" + domain="0.01" /> </param> <param - id="866" + id="1057" group="1" - name="skirt_tight" - label="tight skirt" - clothing_morph="true" - wearable="skirt" - edit_group="skirt" - label_min="form fitting" - label_max="loose" + wearable="underpants" + edit_group="underpants" + name="Pants Waist" value_min="0" - value_max="1"> - <param_morph /> + value_max="1" + value_default=".8"> + <param_alpha + tga_file="pants_waist_alpha.tga" + domain="0.05" /> </param> + </layer> + + <layer + name="lower_underpants"> + <texture + local_texture="lower_underpants" /> <param - id="867" - group="1" - name="skirt_smallbutt" - label="tight skirt" - clothing_morph="false" - wearable="skirt" - edit_group="skirt" - label_min="form fitting" - label_max="loose" + id="824" + group="0" + wearable="underpants" + edit_group="colorpicker" + name="underpants_red" value_min="0" - value_max="1"> - <param_morph /> + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> </param> <param - id="848" + id="825" group="0" - name="skirt_bustle" - label="bustle skirt" - clothing_morph="true" - wearable="skirt" - edit_group_order="3" - edit_group="skirt" - label_min="no bustle" - label_max="more bustle" + wearable="underpants" + edit_group="colorpicker" + name="underpants_green" value_min="0" - value_max="2" - value_default=".2" - camera_angle="100" - camera_distance="1.3" - camera_elevation="-.5"> - <param_morph /> + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> </param> <param - id="847" - group="1" - name="skirt_bowlegs" - label="legs skirt" - wearable="skirt" - value_min="-1" + id="826" + group="0" + wearable="underpants" + edit_group="colorpicker" + name="underpants_blue" + value_min="0" value_max="1" - value_default="0"> - <param_morph /> - </param> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - <param - id="852" - group="1" - name="skirt_bigbutt" - label="bigbutt skirt" - label_min="less" - label_max="more" - value_min="0" - value_max="1"> - <param_morph /> + <value + color="0, 0, 255, 255" /> + </param_color> </param> <param - id="849" + id="1054" group="1" - name="skirt_belly" - label="big belly skirt" + wearable="underpants" + edit_group="driven" + name="Pants Length" value_min="0" - value_max="1"> - <param_morph /> + value_max="1" + value_default=".3" + camera_distance="1.2" + camera_angle="30" + camera_elevation="-.3"> + <param_alpha + tga_file="pants_length_alpha.tga" + domain="0.01" /> </param> <param - id="850" + id="1056" group="1" - name="skirt_saddlebags" - value_min="-.5" - value_max="3"> - <param_morph /> + wearable="underpants" + edit_group="driven" + name="Pants Waist" + value_min="0" + value_max="1" + value_default=".8"> + <param_alpha + tga_file="pants_waist_alpha.tga" + domain="0.05" /> </param> + </layer> + + <layer + name="lower_socks bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="lower_socks" + local_texture_alpha_only="true" /> <param - id="851" + id="1051" group="1" - name="skirt_chubby" - label_min="less" - label_max="more" + wearable="socks" + edit_group="driven" + name="Socks Length bump" value_min="0" value_max="1" - value_default="0"> - <param_morph /> + value_default="0.35"> + <param_alpha + tga_file="shoe_height_alpha.tga" + domain="0.01" /> </param> + </layer> - <param - id="856" - group="1" - name="skirt_lovehandles" - label_min="less" - label_max="more" - value_min="-1" - value_max="2" - value_default="0"> - <param_morph /> - </param> + <layer + name="lower_socks"> + <texture + local_texture="lower_socks" /> -<!-- - ############# - # other morphs (not user controlled) - ############# - --> <param - id="857" - group="1" - name="skirt_male" - value_min="0" - value_max="1"> - <param_morph /> - </param> - </mesh> - - <mesh - type="skirtMesh" - lod="1" - file_name="avatar_skirt_1.llm" - min_pixel_width="160" - reference="avatar_skirt.llm"> - </mesh> - - <mesh - type="skirtMesh" - lod="2" - file_name="avatar_skirt_2.llm" - min_pixel_width="80" - reference="avatar_skirt.llm"> - </mesh> - - <mesh - type="skirtMesh" - lod="3" - file_name="avatar_skirt_3.llm" - min_pixel_width="40" - reference="avatar_skirt.llm"> - </mesh> - - <mesh - type="skirtMesh" - lod="4" - file_name="avatar_skirt_4.llm" - min_pixel_width="0" - reference="avatar_skirt.llm"> - </mesh> - -<!-- =========================================================== --> - <global_color - name="skin_color"> - <param - id="111" + id="818" group="0" - wearable="skin" - edit_group="skin_color" - edit_group_order="1" - name="Pigment" - show_simple="true" - label_min="Light" - label_max="Dark" + wearable="socks" + edit_group="colorpicker" + name="socks_red" value_min="0" value_max="1" - value_default=".5"> - <param_color> - <value - color="252, 215, 200, 255" /> - - <value - color="240, 177, 112, 255" /> - - <value - color="90, 40, 16, 255" /> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - <value - color="29, 9, 6, 255" /> - </param_color> + <value + color="255, 0, 0, 255" /> + </param_color> </param> <param - id="110" + id="819" group="0" - wearable="skin" - edit_group="skin_color" - edit_group_order="2" - name="Red Skin" - label="Ruddiness" - label_min="Pale" - label_max="Ruddy" + wearable="socks" + edit_group="colorpicker" + name="socks_green" value_min="0" - value_max="0.1"> - <param_color - operation="blend"> - <value - color="218, 41, 37, 255" /> - </param_color> + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> </param> <param - id="108" + id="820" group="0" - wearable="skin" - edit_group="skin_color" - edit_group_order="3" - name="Rainbow Color" - show_simple="true" - label_min="None" - label_max="Wild" + wearable="socks" + edit_group="colorpicker" + name="socks_blue" value_min="0" value_max="1" - camera_elevation=".1" - camera_distance=".5"> - <param_color> - <value - color=" 0, 0, 0, 255" /> - - <value - color="255, 0, 255, 255" /> - - <value - color="255, 0, 0, 255" /> - - <value - color="255, 255, 0, 255" /> - - <value - color=" 0, 255, 0, 255" /> - - <value - color=" 0, 255, 255, 255" /> - - <value - color=" 0, 0, 255, 255" /> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - <value - color="255, 0, 255, 255" /> - </param_color> + <value + color="0, 0, 255, 255" /> + </param_color> </param> - </global_color> -<!-- =========================================================== --> - <global_color - name="hair_color"> <param - id="114" - group="0" - wearable="hair" - edit_group="hair_color" - edit_group_order="3" - name="Blonde Hair" - show_simple="true" - label_min="Black" - label_max="Blonde" + id="1050" + group="1" + wearable="socks" + edit_group="driven" + name="Socks Length bump" value_min="0" value_max="1" - value_default=".5" - camera_elevation=".1" - camera_distance=".5"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="22, 6, 6, 255" /> - - <value - color="29, 9, 6, 255" /> - - <value - color="45, 21, 11, 255" /> - - <value - color="78, 39, 11, 255" /> - - <value - color="90, 53, 16, 255" /> - - <value - color="136, 92, 21, 255" /> - - <value - color="150, 106, 33, 255" /> - - <value - color="198, 156, 74, 255" /> - - <value - color="233, 192, 103, 255" /> - - <value - color="238, 205, 136, 255" /> - </param_color> + value_default="0.35"> + <param_alpha + tga_file="shoe_height_alpha.tga" + domain="0.01" /> </param> + </layer> + + <layer + name="lower_shoes bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="lower_shoes" + local_texture_alpha_only="true" /> <param - id="113" - group="0" - wearable="hair" - edit_group="hair_color" - edit_group_order="4" - name="Red Hair" - show_simple="true" - label_min="No Red" - label_max="Very Red" + id="1053" + group="1" + wearable="shoes" + edit_group="driven" + name="Shoe Height bump" value_min="0" value_max="1" - camera_elevation=".1" - camera_distance=".5"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="118, 47, 19, 255" /> - </param_color> + value_default="0.1"> + <param_alpha + tga_file="shoe_height_alpha.tga" + domain="0.01" /> </param> + </layer> + + <layer + name="lower_shoes"> + <texture + local_texture="lower_shoes" /> <param - id="115" + id="812" group="0" - wearable="hair" - edit_group="hair_color" - edit_group_order="1" - name="White Hair" - show_simple="true" - label_min="No White" - label_max="All White" + wearable="shoes" + edit_group="colorpicker" + name="shoes_red" value_min="0" value_max="1" - camera_elevation=".1" - camera_distance=".5"> - <param_color> - <value - color="0, 0, 0, 255" /> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - <value - color="255, 255, 255, 255" /> - </param_color> + <value + color="255, 0, 0, 255" /> + </param_color> </param> <param - id="112" + id="813" group="0" - wearable="hair" - edit_group="hair_color" - edit_group_order="2" - name="Rainbow Color" - show_simple="true" - label_min="None" - label_max="Wild" + wearable="shoes" + edit_group="colorpicker" + name="shoes_green" value_min="0" value_max="1" - camera_elevation=".1" - camera_distance=".5"> - <param_color> - <value - color=" 0, 0, 0, 255" /> - - <value - color="255, 0, 255, 255" /> - - <value - color="255, 0, 0, 255" /> - - <value - color="255, 255, 0, 255" /> - - <value - color=" 0, 255, 0, 255" /> - - <value - color=" 0, 255, 255, 255" /> - - <value - color=" 0, 0, 255, 255" /> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - <value - color="255, 0, 255, 255" /> - </param_color> + <value + color="0, 255, 0, 255" /> + </param_color> </param> - </global_color> -<!-- =========================================================== --> - <global_color - name="eye_color"> <param - id="99" + id="817" group="0" - wearable="eyes" - edit_group="eyes" - edit_group_order="1" - name="Eye Color" - show_simple="true" - label_min="Natural" - label_max="Unnatural" + wearable="shoes" + edit_group="colorpicker" + name="shoes_blue" value_min="0" value_max="1" - value_default="0" - camera_elevation=".1" - camera_distance=".3"> -<!-- default to natural brown eyes--> - <param_color> - <value - color="50, 25, 5, 255" /> - -<!-- natural dark brown eyes--> - <value - color="109, 55, 15, 255" /> - -<!-- natural brown eyes--> - <value - color="150, 93, 49, 255" /> - -<!-- natural light brown eyes--> - <value - color="152, 118, 25, 255" /> - -<!--natural hazel eyes--> - <value - color="95, 179, 107, 255" /> - -<!--natural green eyes--> - <value - color="87, 192, 191, 255" /> - -<!--natural aqua eyes--> - <value - color="95, 172, 179, 255" /> - -<!--natural blue eyes--> - <value - color="128, 128, 128, 255" /> - -<!--natural grey eyes--> - <value - color="0, 0, 0, 255" /> - -<!--black eyes--> - <value - color="255, 255, 0, 255" /> - -<!--bright yellow eyes--> - <value - color=" 0, 255, 0, 255" /> - -<!-- bright green eyes--> - <value - color=" 0, 255, 255, 255" /> - -<!-- bright cyan eyes--> - <value - color=" 0, 0, 255, 255" /> - -<!--bright blue eyes--> - <value - color="255, 0, 255, 255" /> - -<!-- bright violet eyes--> - <value - color="255, 0, 0, 255" /> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> -<!--bright red eyes--> - </param_color> + <value + color="0, 0, 255, 255" /> + </param_color> </param> <param - id="98" - group="0" - wearable="eyes" - edit_group="eyes" - edit_group_order="2" - name="Eye Lightness" - show_simple="true" - label_min="Darker" - label_max="Lighter" + id="1052" + group="1" + wearable="shoes" + edit_group="driven" + name="Shoe Height" value_min="0" value_max="1" - camera_elevation=".1" - camera_distance=".3"> - <param_color> - <value - color="0, 0, 0, 0" /> - - <value - color="255, 255, 255, 255" /> - </param_color> + value_default="0.1"> + <param_alpha + tga_file="shoe_height_alpha.tga" + domain="0.01" /> </param> - </global_color> - -<!-- =========================================================== --> - <layer_set - body_region="hair" - width="512" - height="512" - clear_alpha="false"> - <layer - name="base" - global_color="hair_color" - write_all_channels="true"> - <texture - local_texture="hair_grain" /> </layer> <layer - name="hair alpha" - visibility_mask="TRUE"> + name="lower_clothes_shadow"> <texture - local_texture="hair_alpha" /> - </layer> + local_texture="lower_pants" /> - </layer_set> - <!-- =========================================================== --> - - <layer_set - body_region="head" - width="512" - height="512" - clear_alpha="false" - alpha_tga_file="head_alpha.tga"> - <layer - name="head bump base" - fixed_color = "128,128,128,255" - render_pass="bump"> - </layer> - - <layer - name="head bump definition" - render_pass="bump"> - - <texture - tga_file="bump_head_base.tga" - file_is_mask="FALSE"/> - - <param - id="873" - group="1" - wearable="skin" - edit_group="driven" - edit_group_order="12" - name="Bump base" - value_min="0" - value_max="1"> - <param_alpha - domain="0" /> - </param> - </layer> - - <layer - name="base" - global_color="skin_color"> - <texture - tga_file="head_skingrain.tga" /> - </layer> - - <layer - name="headcolor"> - <texture - tga_file="head_color.tga" /> - </layer> - - <layer - name="shadow"> - <texture - tga_file="head_shading_alpha.tga" - file_is_mask="TRUE" /> - - <param - id="158" - group="1" - wearable="skin" - name="Shading" - value_min="0" - value_max="1"> - <param_color> - <value - color="0, 0, 0, 0" /> - - <value - color="0, 0, 0, 128" /> - </param_color> - </param> - </layer> - - <layer - name="highlight"> - <texture - tga_file="head_highlights_alpha.tga" - file_is_mask="TRUE" /> - - - <param - id="159" - group="1" - name="Shading" - wearable="skin" - value_min="0" - value_max="1"> - <param_color> - <value - color="255, 255, 255, 0" /> - - - <value - color="255, 255, 255, 64" /> - </param_color> - </param> - </layer> - <layer - name="rosyface"> - <texture - tga_file="rosyface_alpha.tga" - file_is_mask="true" /> - - <param - id="116" - group="0" - wearable="skin" - edit_group="skin_facedetail" - edit_group_order="4" - name="Rosy Complexion" - label_min="Less Rosy" - label_max="More Rosy" - value_min="0" - value_max="1" - camera_distance=".3" - camera_elevation=".07"> - <param_color> - <value - color="198, 71, 71, 0" /> - - <value - color="198, 71, 71, 255" /> - </param_color> - </param> - </layer> - - <layer - name="lips"> - <texture - tga_file="lips_mask.tga" - file_is_mask="true" /> - - <param - id="117" - group="0" - wearable="skin" - edit_group="skin_facedetail" - edit_group_order="5" - name="Lip Pinkness" - label_min="Darker" - label_max="Pinker" - value_min="0" - value_max="1" - camera_distance=".25"> - <param_color> - <value - color="220, 115, 115, 0" /> - - <value - color="220, 115, 115, 128" /> - </param_color> - </param> - </layer> - - <layer - name="wrinkles_shading" - render_pass="bump" - fixed_color="0,0,0,100"> - <param - id="118" - group="1" - wearable="skin" - name="Wrinkles" - value_min="0" - value_max="1"> - <param_alpha - tga_file="bump_face_wrinkles.tga" - skip_if_zero="true" - domain="0.3" /> - </param> - </layer> - -<!--<layer - name="wrinkles_highlights" - fixed_color="255,255,255,64"> - <param - id="128" - group="1" - name="Wrinkles" - value_min="0" - value_max="1"> - <param_alpha - tga_file="head_wrinkles_highlights_alpha.tga" - skip_if_zero="true" - domain="0.3" /> - </param> - </layer>--> - <layer - name="freckles" - fixed_color="120,47,20,128"> - <param - id="165" - group="0" - wearable="skin" - edit_group="skin_facedetail" - edit_group_order="2" - name="Freckles" - label_min="Less" - label_max="More" - value_min="0" - value_max="1" - camera_distance=".3" - camera_elevation=".07"> - <param_alpha - tga_file="freckles_alpha.tga" - skip_if_zero="true" - domain="0.5" /> - </param> - </layer> - <layer - name="eyebrowsbump" - render_pass="bump"> - <texture - tga_file="head_hair.tga" - file_is_mask="false" /> - - <param - id="1000" - group="1" - wearable="hair" - edit_group="driven" - name="Eyebrow Size Bump" - value_min="0" - value_max="1"> - <param_alpha - tga_file="eyebrows_alpha.tga" - domain="0.1" /> - </param> - - <param - id="1002" - group="1" - wearable="hair" - edit_group="driven" - name="Eyebrow Density Bump" - value_min="0" - value_max="1"> - <param_color> - <value - color="255,255,255,0" /> - - <value - color="255,255,255,255" /> - </param_color> - </param> - </layer> - - <layer - name="eyebrows" - global_color="hair_color"> - <texture - tga_file="head_hair.tga" - file_is_mask="false" /> - - <param - id="1001" - group="1" - wearable="hair" - edit_group="hair_eyebrows" - name="Eyebrow Size" - show_simple="true" - value_min="0" - value_max="1" - value_default="0.5"> - <param_alpha - tga_file="eyebrows_alpha.tga" - domain="0.1" /> - </param> - - <param - id="1003" - group="1" - edit_group="driven" - name="Eyebrow Density" - value_min="0" - value_max="1"> - <param_color - operation="multiply"> - <value - color="255,255,255,0" /> - - <value - color="255,255,255,255" /> - </param_color> - </param> - </layer> - - <layer - name="lipstick"> - <param - id="700" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="2" - name="Lipstick Color" - label_min="Pink" - label_max="Black" - value_min="0" - value_max="1" - value_default=".25" - camera_distance=".25"> - <param_color> - <value - color="245,161,177,200" /> - - <value - color="216,37,67,200" /> - - <value - color="178,48,76,200" /> - - <value - color="68,0,11,200" /> - - <value - color="252,207,184,200" /> - - <value - color="241,136,106,200" /> - - <value - color="208,110,85,200" /> - - <value - color="106,28,18,200" /> - - <value - color="58,26,49,200" /> - - <value - color="14,14,14,200" /> - </param_color> - </param> - - <param - id="701" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="1" - name="Lipstick" - label_min="No Lipstick" - label_max="More Lipstick" - value_min="0" - value_max=".9" - value_default="0.0" - camera_distance=".25"> - <param_alpha - tga_file="lipstick_alpha.tga" - skip_if_zero="true" - domain="0.05" /> - </param> - </layer> - - <layer - name="lipgloss" - fixed_color="255,255,255,190"> - <param - id="702" - name="Lipgloss" - label_min="No Lipgloss" - label_max="Glossy" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="3" - group="0" - value_min="0" - value_max="1" - camera_distance=".25"> - <param_alpha - tga_file="lipgloss_alpha.tga" - skip_if_zero="true" - domain="0.2" /> - </param> - </layer> - - <layer - name="blush"> - <param - id="704" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="4" - name="Blush" - label_min="No Blush" - label_max="More Blush" - value_min="0" - value_max=".9" - value_default="0" - camera_distance=".3" - camera_elevation=".07" - camera_angle="20"> - <param_alpha - tga_file="blush_alpha.tga" - skip_if_zero="true" - domain="0.3" /> - </param> - - <param - id="705" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="5" - name="Blush Color" - label_min="Pink" - label_max="Orange" - value_min="0" - value_max="1" - value_default=".5" - camera_distance=".3" - camera_elevation=".07" - camera_angle="20"> - <param_color> - <value - color="253,162,193,200" /> - - <value - color="247,131,152,200" /> - - <value - color="213,122,140,200" /> - - <value - color="253,152,144,200" /> - - <value - color="236,138,103,200" /> - - <value - color="195,128,122,200" /> - - <value - color="148,103,100,200" /> - - <value - color="168,95,62,200" /> - </param_color> - </param> - - <param - id="711" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="6" - name="Blush Opacity" - label_min="Clear" - label_max="Opaque" - value_min="0" - value_max="1" - value_default=".5" - camera_distance=".3" - camera_elevation=".07" - camera_angle="20"> - <param_color - operation="multiply"> - <value - color="255,255,255,0" /> - - <value - color="255,255,255,255" /> - </param_color> - </param> - </layer> - - <layer - name="Outer Eye Shadow"> - <param - id="708" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="11" - name="Out Shdw Color" - label_min="Light" - label_max="Dark" - value_min="0" - value_max="1" - camera_distance=".3" - camera_elevation=".14"> - <param_color> - <value - color="252,247,246,255" /> - - <value - color="255,206,206,255" /> - - <value - color="233,135,149,255" /> - - <value - color="220,168,192,255" /> - - <value - color="228,203,232,255" /> - - <value - color="255,234,195,255" /> - - <value - color="230,157,101,255" /> - - <value - color="255,147,86,255" /> - - <value - color="228,110,89,255" /> - - <value - color="228,150,120,255" /> - - <value - color="223,227,213,255" /> - - <value - color="96,116,87,255" /> - - <value - color="88,143,107,255" /> - - <value - color="194,231,223,255" /> - - <value - color="207,227,234,255" /> - - <value - color="41,171,212,255" /> - - <value - color="180,137,130,255" /> - - <value - color="173,125,105,255" /> - - <value - color="144,95,98,255" /> - - <value - color="115,70,77,255" /> - - <value - color="155,78,47,255" /> - - <value - color="239,239,239,255" /> - - <value - color="194,194,194,255" /> - - <value - color="120,120,120,255" /> - - <value - color="10,10,10,255" /> - </param_color> - </param> - - <param - id="706" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="12" - name="Out Shdw Opacity" - label_min="Clear" - label_max="Opaque" - value_min=".2" - value_max="1" - value_default=".6" - camera_distance=".3" - camera_elevation=".14"> - <param_color - operation="multiply"> - <value - color="255,255,255,0" /> - - <value - color="255,255,255,255" /> - </param_color> - </param> - - <param - id="707" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="10" - name="Outer Shadow" - label_min="No Eyeshadow" - label_max="More Eyeshadow" - value_min="0" - value_max=".7" - camera_distance=".3" - camera_elevation=".14"> - <param_alpha - tga_file="eyeshadow_outer_alpha.tga" - skip_if_zero="true" - domain="0.05" /> - </param> - </layer> - - <layer - name="Inner Eye Shadow"> - <param - id="712" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="8" - name="In Shdw Color" - label_min="Light" - label_max="Dark" - value_min="0" - value_max="1" - camera_distance=".3" - camera_elevation=".14"> - <param_color> - <value - color="252,247,246,255" /> - - <value - color="255,206,206,255" /> - - <value - color="233,135,149,255" /> - - <value - color="220,168,192,255" /> - - <value - color="228,203,232,255" /> - - <value - color="255,234,195,255" /> - - <value - color="230,157,101,255" /> - - <value - color="255,147,86,255" /> - - <value - color="228,110,89,255" /> - - <value - color="228,150,120,255" /> - - <value - color="223,227,213,255" /> - - <value - color="96,116,87,255" /> - - <value - color="88,143,107,255" /> - - <value - color="194,231,223,255" /> - - <value - color="207,227,234,255" /> - - <value - color="41,171,212,255" /> - - <value - color="180,137,130,255" /> - - <value - color="173,125,105,255" /> - - <value - color="144,95,98,255" /> - - <value - color="115,70,77,255" /> - - <value - color="155,78,47,255" /> - - <value - color="239,239,239,255" /> - - <value - color="194,194,194,255" /> - - <value - color="120,120,120,255" /> - - <value - color="10,10,10,255" /> - </param_color> - </param> - - <param - id="713" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="9" - name="In Shdw Opacity" - label_min="Clear" - label_max="Opaque" - value_min=".2" - value_max="1" - value_default=".7" - camera_distance=".3" - camera_elevation=".14"> - <param_color - operation="multiply"> - <value - color="255,255,255,0" /> - - <value - color="255,255,255,255" /> - </param_color> - </param> - - <param - id="709" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="7" - name="Inner Shadow" - label_min="No Eyeshadow" - label_max="More Eyeshadow" - value_min="0" - value_max="1" - value_default="0" - camera_distance=".3" - camera_elevation=".14"> - <param_alpha - tga_file="eyeshadow_inner_alpha.tga" - skip_if_zero="true" - domain="0.2" /> - </param> - </layer> - - <layer - name="eyeliner" - fixed_color="0,0,0,200"> - <param - id="703" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="13" - name="Eyeliner" - label_min="No Eyeliner" - label_max="Full Eyeliner" - value_min="0" - value_max="1" - value_default="0.0" - camera_distance=".3" - camera_elevation=".14"> - <param_alpha - tga_file="eyeliner_alpha.tga" - skip_if_zero="true" - domain="0.1" /> - </param> - - <param - id="714" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="14" - name="Eyeliner Color" - label_min="Dark Green" - label_max="Black" - value_min="0" - value_max="1" - camera_distance=".3" - camera_elevation=".14"> - <param_color> - <value - color="24,98,40,250" /> - -<!-- dark green --> - <value - color="9,100,127,250" /> - -<!-- lt.aqua blue --> - <value - color="61,93,134,250" /> - -<!-- aqua --> - <value - color="70,29,27,250" /> - -<!-- dark brown --> - <value - color="115,75,65,250" /> - -<!-- lt. brown blue --> - <value - color="100,100,100,250" /> - -<!-- grey --> - <value - color="91,80,74,250" /> - -<!-- grey/brown --> - <value - color="112,42,76,250" /> - -<!-- plum --> - <value - color="14,14,14,250" /> - -<!-- black --> - </param_color> - </param> - </layer> - - <layer - name="facialhair bump" - render_pass="bump"> - <texture - tga_file="head_hair.tga" - file_is_mask="false" /> - - <param - id="1004" - sex="male" - group="1" - wearable="hair" - edit_group="driven" - name="Sideburns bump" - value_min="0" - value_max="1"> - <param_alpha - tga_file="facehair_sideburns_alpha.tga" - skip_if_zero="true" - domain="0.05" /> - </param> - - <param - id="1006" - sex="male" - group="1" - wearable="hair" - edit_group="driven" - name="Moustache bump" - value_min="0" - value_max="1"> - <param_alpha - tga_file="facehair_moustache_alpha.tga" - skip_if_zero="true" - domain="0.05" /> - </param> - - <param - id="1008" - sex="male" - group="1" - wearable="hair" - edit_group="driven" - name="Soulpatch bump" - value_min="0" - value_max="1"> - <param_alpha - tga_file="facehair_soulpatch_alpha.tga" - skip_if_zero="true" - domain="0.1" /> - </param> - - <param - id="1010" - sex="male" - group="1" - edit_group="driven" - wearable="hair" - name="Chin Curtains bump" - value_min="0" - value_max="1"> - <param_alpha - tga_file="facehair_chincurtains_alpha.tga" - skip_if_zero="true" - domain="0.03" /> - </param> - - <param - id="1012" - group="1" - sex="male" - wearable="hair" - edit_group="driven" - name="5 O'Clock Shadow bump" - value_min="0" - value_max="1"> - <param_color> - <value - color="255,255,255,255" /> - - <value - color="255,255,255,0" /> - </param_color> - </param> - </layer> - - <layer - name="facialhair" - global_color="hair_color"> - - <texture - tga_file="head_hair.tga" - file_is_mask="false" /> - - <param - id="1005" - sex="male" - group="1" - edit_group="driven" - name="Sideburns" - value_min="0" - value_max="1"> - <param_alpha - tga_file="facehair_sideburns_alpha.tga" - skip_if_zero="true" - domain="0.05" /> - </param> - - <param - id="1007" - sex="male" - group="1" - edit_group="driven" - name="Moustache" - value_min="0" - value_max="1"> - <param_alpha - tga_file="facehair_moustache_alpha.tga" - skip_if_zero="true" - domain="0.05" /> - </param> - - <param - id="1009" - sex="male" - group="1" - edit_group="driven" - name="Soulpatch" - value_min="0" - value_max="1"> - <param_alpha - tga_file="facehair_soulpatch_alpha.tga" - skip_if_zero="true" - domain="0.1" /> - </param> - - <param - id="1011" - sex="male" - group="1" - edit_group="driven" - name="Chin Curtains" - value_min="0" - value_max="1"> - <param_alpha - tga_file="facehair_chincurtains_alpha.tga" - skip_if_zero="true" - domain="0.03" /> - </param> - - <param - id="751" - group="1" - wearable="hair" - sex="male" - edit_group="hair_facial" - name="5 O'Clock Shadow" - label_min="Dense hair" - label_max="Shadow hair" - value_min="0" - value_max="1" - value_default="0.7" - camera_elevation=".1" - camera_distance=".3"> - <param_color - operation="multiply"> - <value - color="255,255,255,255" /> - - <value - color="255,255,255,30" /> - </param_color> - </param> - </layer> - - <layer - name="head_bodypaint"> - <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> - -<!-- =========================================================== --> - <layer_set - body_region="upper_body" - width="512" - height="512"> - <layer - name="base_upperbody bump" - render_pass="bump" - fixed_color="128,128,128,255"> - </layer> - <layer - name="upperbody bump definition" - render_pass="bump"> - <texture - tga_file="bump_upperbody_base.tga" - file_is_mask="FALSE"/> - - <param - id="874" - group="1" - wearable="skin" - edit_group="driven" - edit_group_order="20" - name="Bump upperdef" - value_min="0" - value_max="1"> - <param_alpha - domain="0" /> - </param> - </layer> - - <layer - name="base" - global_color="skin_color"> - <texture - tga_file="body_skingrain.tga" /> - </layer> - - <layer - name="nipples"> - <texture - tga_file="upperbody_color.tga" /> - </layer> - - <layer - name="shadow"> - <texture - tga_file="upperbody_shading_alpha.tga" - file_is_mask="TRUE" /> - - <param - id="125" - group="1" - name="Shading" - wearable="skin" - value_min="0" - value_max="1"> - <param_color> - <value - color="0, 0, 0, 0" /> - - <value - color="0, 0, 0, 128" /> - </param_color> - </param> - </layer> - - <layer - name="highlight"> - <texture - tga_file="upperbody_highlights_alpha.tga" - file_is_mask="TRUE" /> - - <param - id="126" - group="1" - wearable="skin" - name="Shading" - value_min="0" - value_max="1"> - <param_color> - <value - color="255, 255, 255, 0" /> - - <value - color="255, 255, 255, 64" /> - </param_color> - </param> - </layer> - - <layer - name="upper_bodypaint"> - <texture - local_texture="upper_bodypaint" /> - </layer> - - <layer - name="freckles upper" - fixed_color="120,47,20,128"> - <param - id="776" - group="1" - name="freckles upper" - wearable="skin" - value_min="0" - value_max="1"> - <param_alpha - tga_file="upperbodyfreckles_alpha.tga" - skip_if_zero="true" - domain="0.6" /> - </param> - </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"> - <texture - local_texture="upper_undershirt" - local_texture_alpha_only="true" /> - - <param - id="1043" - group="1" - wearable="undershirt" - edit_group="driven" - name="Sleeve Length bump" - value_min=".01" - value_max="1" - value_default=".4"> - <param_alpha - tga_file="shirt_sleeve_alpha.tga" - multiply_blend="false" - domain="0.01" /> - </param> - - <param - id="1045" - group="1" - wearable="undershirt" - edit_group="undershirt" - edit_group_order="2" - name="Bottom bump" - value_min="0" - value_max="1" - value_default=".8"> - <param_alpha - tga_file="shirt_bottom_alpha.tga" - multiply_blend="true" - domain="0.05" /> - </param> - - <param - id="1047" - group="1" - wearable="undershirt" - edit_group="driven" - name="Collar Front bump" - value_min="0" - value_max="1" - value_default=".8"> - <param_alpha - tga_file="shirt_collar_alpha.tga" - multiply_blend="true" - domain="0.05" /> - </param> - - <param - id="1049" - group="1" - wearable="undershirt" - edit_group="driven" - name="Collar Back bump" - value_min="0" - value_max="1" - value_default=".8"> - <param_alpha - tga_file="shirt_collar_back_alpha.tga" - multiply_blend="true" - domain="0.05" /> - </param> - </layer> - - <layer - name="upper_undershirt"> - <texture - local_texture="upper_undershirt" /> - - <param - id="821" - group="0" - wearable="undershirt" - edit_group="colorpicker" - name="undershirt_red" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="255, 0, 0, 255" /> - </param_color> - </param> - - <param - id="822" - group="0" - wearable="undershirt" - edit_group="colorpicker" - name="undershirt_green" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 255, 0, 255" /> - </param_color> - </param> - - <param - id="823" - group="0" - wearable="undershirt" - edit_group="colorpicker" - name="undershirt_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 0, 255, 255" /> - </param_color> - </param> - - <param - id="1042" - group="1" - wearable="undershirt" - edit_group="driven" - name="Sleeve Length" - value_min=".01" - value_max="1" - value_default=".4"> - <param_alpha - tga_file="shirt_sleeve_alpha.tga" - multiply_blend="false" - domain="0.01" /> - </param> - - <param - id="1044" - group="1" - wearable="undershirt" - edit_group="driven" - name="Bottom" - value_min="0" - value_max="1" - value_default=".8"> - <param_alpha - tga_file="shirt_bottom_alpha.tga" - multiply_blend="true" - domain="0.05" /> - </param> - - <param - id="1046" - group="1" - wearable="undershirt" - edit_group="driven" - name="Collar Front" - value_min="0" - value_max="1" - value_default=".8"> - <param_alpha - tga_file="shirt_collar_alpha.tga" - multiply_blend="true" - domain="0.05" /> - </param> - - <param - id="1048" - group="1" - wearable="undershirt" - edit_group="driven" - name="Collar Back" - label_min="Low" - label_max="High" - value_min="0" - value_max="1" - value_default=".8"> - <param_alpha - tga_file="shirt_collar_back_alpha.tga" - multiply_blend="true" - domain="0.05" /> - </param> - </layer> - - <layer - name="Nail Polish"> - <param - id="710" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="15" - name="Nail Polish" - label_min="No Polish" - label_max="Painted Nails" - value_min="0" - value_max="1" - value_default="0.0" - camera_distance="1.6" - camera_elevation="-.4" - camera_angle="70"> - <param_alpha - tga_file="nailpolish_alpha.tga" - skip_if_zero="true" - domain="0.1" /> - </param> - - <param - id="715" - group="0" - wearable="skin" - edit_group="skin_makeup" - edit_group_order="16" - name="Nail Polish Color" - label_min="Pink" - label_max="Black" - value_min="0" - value_max="1" - camera_distance="1.6" - camera_elevation="-.4" - camera_angle="70"> - <param_color> - <value - color="255,187,200,255" /> - - <value - color="194,102,127,255" /> - - <value - color="227,34,99,255" /> - - <value - color="168,41,60,255" /> - - <value - color="97,28,59,255" /> - - <value - color="234,115,93,255" /> - - <value - color="142,58,47,255" /> - - <value - color="114,30,46,255" /> - - <value - color="14,14,14,255" /> - </param_color> - </param> - </layer> - - <layer - name="upper_gloves bump" - render_pass="bump" - fixed_color="128,128,128,255"> - <texture - local_texture="upper_gloves" - local_texture_alpha_only="true" /> - - <param - id="1059" - group="1" - wearable="gloves" - edit_group="driven" - name="Glove Length bump" - value_min=".01" - value_max="1" - value_default=".8"> - <param_alpha - tga_file="glove_length_alpha.tga" - domain="0.01" /> - </param> - - <param - id="1061" - group="1" - wearable="gloves" - edit_group="driven" - name="Glove Fingers bump" - value_min=".01" - value_max="1" - value_default="1"> - <param_alpha - tga_file="gloves_fingers_alpha.tga" - multiply_blend="true" - domain="0.01" /> - </param> - </layer> - - <layer - name="upper_gloves"> - <texture - local_texture="upper_gloves" /> - - <param - id="827" - group="0" - wearable="gloves" - edit_group="colorpicker" - name="gloves_red" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="255, 0, 0, 255" /> - </param_color> - </param> - - <param - id="829" - group="0" - wearable="gloves" - edit_group="colorpicker" - name="gloves_green" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 255, 0, 255" /> - </param_color> - </param> - - <param - id="830" - group="0" - wearable="gloves" - edit_group="colorpicker" - name="gloves_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 0, 255, 255" /> - </param_color> - </param> - - <param - id="1058" - group="1" - wearable="gloves" - edit_group="driven" - name="Glove Length" - value_min=".01" - value_max="1" - value_default=".8"> - <param_alpha - tga_file="glove_length_alpha.tga" - domain="0.01" /> - </param> - - <param - id="1060" - group="1" - wearable="gloves" - edit_group="driven" - name="Glove Fingers" - value_min=".01" - value_max="1" - value_default="1"> - <param_alpha - tga_file="gloves_fingers_alpha.tga" - multiply_blend="true" - domain="0.01" /> - </param> - </layer> - - <layer - name="upper_clothes_shadow"> - <texture - local_texture="upper_shirt" /> - - <param - id="899" - group="1" - edit_group="driven" - wearable="shirt" - name="Upper Clothes Shading" - value_min="0" - value_max="1" - value_default="0"> - <param_color> - <value - color="0, 0, 0, 0" /> - - <value - color="0, 0, 0, 80" /> - </param_color> - </param> - - <param - id="900" - group="1" - wearable="shirt" - edit_group="driven" - name="Sleeve Length Shadow" - value_min="0.02" - value_max=".87" - value_default="0.02"> - <param_alpha - multiply_blend="false" - tga_file="shirt_sleeve_alpha.tga" - skip_if_zero="true" - domain="0.03" /> - </param> - - <param - id="901" - group="1" - wearable="shirt" - edit_group="driven" - name="Shirt Shadow Bottom" - value_min="0.02" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_bottom_alpha.tga" - skip_if_zero="true" - domain="0.05" /> - </param> - - <param - id="902" - group="1" - wearable="shirt" - edit_group="driven" - name="Collar Front Shadow Height" - value_min="0.02" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_alpha.tga" - skip_if_zero="true" - domain="0.02" /> - </param> - - <param - id="903" - group="1" - wearable="shirt" - edit_group="driven" - name="Collar Back Shadow Height" - value_min="0.02" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_back_alpha.tga" - skip_if_zero="true" - domain="0.02" /> - </param> - </layer> - - <layer - name="upper_shirt base bump" - render_pass="bump" - fixed_color="128,128,128,255"> - <texture - local_texture="upper_shirt" - local_texture_alpha_only="true" /> - - <param - id="1029" - group="1" - wearable="shirt" - edit_group="driven" - name="Sleeve Length Cloth" - value_min="0" - value_max="0.85"> - <param_alpha - multiply_blend="false" - tga_file="shirt_sleeve_alpha.tga" - domain="0.01" /> - </param> - - <param - id="1030" - group="1" - wearable="shirt" - edit_group="driven" - name="Shirt Bottom Cloth" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_bottom_alpha.tga" - domain="0.05" /> - </param> - - <param - id="1031" - group="1" - wearable="shirt" - edit_group="driven" - name="Collar Front Height Cloth" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_alpha.tga" - domain="0.05" /> - </param> - - <param - id="1032" - group="1" - wearable="shirt" - edit_group="driven" - name="Collar Back Height Cloth" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_back_alpha.tga" - domain="0.05" /> - </param> - </layer> - - <layer - name="upper_clothes bump" - render_pass="bump"> - <texture - tga_file="bump_shirt_wrinkles.tga" /> - - <texture - local_texture="upper_shirt" - local_texture_alpha_only="true" /> - - <param - id="868" - group="0" - wearable="shirt" - edit_group="shirt" - edit_group_order="8" - name="Shirt Wrinkles" - value_min="0" - value_max="1" - value_default="0"> - <param_color> - <value - color="255, 255, 255, 0" /> - - <value - color="255, 255, 255, 255" /> - </param_color> - </param> - - <param - id="1013" - group="1" - wearable="shirt" - edit_group="driven" - name="Sleeve Length Cloth" - value_min="0" - value_max="0.85"> - <param_alpha - multiply_blend="false" - tga_file="shirt_sleeve_alpha.tga" - domain="0.01" /> - </param> - - <param - id="1014" - group="1" - wearable="shirt" - edit_group="driven" - name="Shirt Bottom Cloth" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_bottom_alpha.tga" - domain="0.05" /> - </param> - - <param - id="1015" - group="1" - wearable="shirt" - edit_group="driven" - name="Collar Front Height Cloth" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_alpha.tga" - domain="0.05" /> - </param> - - <param - id="1016" - group="1" - wearable="shirt" - edit_group="driven" - name="Collar Back Height Cloth" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_back_alpha.tga" - domain="0.05" /> - </param> - </layer> - - <layer - name="upper_clothes"> - <texture - local_texture="upper_shirt" /> - - <param - id="803" - group="0" - wearable="shirt" - edit_group="colorpicker" - name="shirt_red" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="255, 0, 0, 255" /> - </param_color> - </param> - - <param - id="804" - group="0" - wearable="shirt" - edit_group="colorpicker" - name="shirt_green" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 255, 0, 255" /> - </param_color> - </param> - - <param - id="805" - group="0" - wearable="shirt" - edit_group="colorpicker" - name="shirt_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 0, 255, 255" /> - </param_color> - </param> - - <param - id="600" - group="1" - wearable="shirt" - edit_group="driven" - name="Sleeve Length Cloth" - value_min="0" - value_max="0.85" - value_default=".7"> - <param_alpha - multiply_blend="false" - tga_file="shirt_sleeve_alpha.tga" - domain="0.01" /> - </param> - - <param - id="601" - group="1" - wearable="shirt" - edit_group="driven" - name="Shirt Bottom Cloth" - value_min="0" - value_max="1" - value_default=".8"> - <param_alpha - multiply_blend="true" - tga_file="shirt_bottom_alpha.tga" - domain="0.05" /> - </param> - - <param - id="602" - group="1" - wearable="shirt" - edit_group="driven" - name="Collar Front Height Cloth" - value_min="0" - value_max="1" - value_default=".8"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_alpha.tga" - domain="0.05" /> - </param> - - <param - id="778" - group="1" - wearable="shirt" - edit_group="driven" - name="Collar Back Height Cloth" - value_min="0" - value_max="1" - value_default=".8"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_back_alpha.tga" - domain="0.05" /> - </param> - </layer> - - <layer - name="upper_jacket base bump" - render_pass="bump" - fixed_color="128,128,128,255"> - <texture - local_texture="upper_jacket" - local_texture_alpha_only="true" /> - - <param - id="1039" - group="1" - wearable="jacket" - edit_group="driven" - edit_group_order="1" - name="Jacket Sleeve Length bump" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="false" - tga_file="shirt_sleeve_alpha.tga" - domain="0.01" /> - </param> - - <param - id="1040" - group="1" - wearable="jacket" - edit_group="driven" - name="Jacket Collar Front bump" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_alpha.tga" - domain="0.05" /> - </param> - - <param - id="1041" - group="1" - wearable="jacket" - edit_group="driven" - edit_group_order="3.5" - name="Jacket Collar Back bump" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_back_alpha.tga" - domain="0.05" /> - </param> - - <param - id="1037" - group="1" - wearable="jacket" - edit_group="driven" - name="jacket bottom length upper bump" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="jacket_length_upper_alpha.tga" - domain="0.01" /> - </param> - - <param - id="1038" - group="1" - wearable="jacket" - edit_group="driven" - name="jacket open upper bump" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="jacket_open_upper_alpha.tga" - domain="0.01" /> - </param> - </layer> - - <layer - name="upper_jacket bump" - render_pass="bump"> - <texture - tga_file="bump_shirt_wrinkles.tga" /> - - <texture - local_texture="upper_jacket" - local_texture_alpha_only="true" /> - - <param - id="875" - group="1" - wearable="jacket" - name="jacket upper Wrinkles" - value_min="0" - value_max="1" - value_default="0"> - <param_color> - <value - color="255, 255, 255, 0" /> - - <value - color="255, 255, 255, 255" /> - </param_color> - </param> - - <param - id="1019" - group="1" - wearable="jacket" - edit_group="driven" - edit_group_order="1" - name="Jacket Sleeve Length bump" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="false" - tga_file="shirt_sleeve_alpha.tga" - domain="0.01" /> - </param> - - <param - id="1021" - group="1" - wearable="jacket" - edit_group="driven" - name="Jacket Collar Front bump" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_alpha.tga" - domain="0.05" /> - </param> - - <param - id="1023" - group="1" - wearable="jacket" - edit_group="driven" - edit_group_order="3.5" - name="Jacket Collar Back bump" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_back_alpha.tga" - domain="0.05" /> - </param> - - <param - id="1025" - group="1" - wearable="jacket" - edit_group="driven" - name="jacket bottom length upper bump" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="jacket_length_upper_alpha.tga" - domain="0.01" /> - </param> - - <param - id="1026" - group="1" - wearable="jacket" - edit_group="driven" - name="jacket open upper bump" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="jacket_open_upper_alpha.tga" - domain="0.01" /> - </param> - </layer> - - <layer - name="upper_jacket"> - <texture - local_texture="upper_jacket" /> - - <param - id="831" - group="1" - edit_group="colorpicker_driven" - wearable="jacket" - name="upper_jacket_red" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="255, 0, 0, 255" /> - </param_color> - </param> - - <param - id="832" - group="1" - edit_group="colorpicker_driven" - wearable="jacket" - name="upper_jacket_green" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 255, 0, 255" /> - </param_color> - </param> - - <param - id="833" - group="1" - edit_group="colorpicker_driven" - wearable="jacket" - name="upper_jacket_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 0, 255, 255" /> - </param_color> - </param> - - <param - id="1020" - group="1" - edit_group="driven" - name="jacket Sleeve Length" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="false" - tga_file="shirt_sleeve_alpha.tga" - domain="0.01" /> - </param> - - <param - id="1022" - group="1" - edit_group="driven" - name="jacket Collar Front" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_alpha.tga" - domain="0.05" /> - </param> - - <param - id="1024" - group="1" - edit_group="driven" - edit_group_order="3.5" - name="jacket Collar Back" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="shirt_collar_back_alpha.tga" - domain="0.05" /> - </param> - - <param - id="620" - group="1" - wearable="jacket" - edit_group="jacket" - name="bottom length upper" - label_min="hi cut" - label_max="low cut" - value_min="0" - value_max="1" - value_default=".8" - camera_distance="1.2" - camera_angle="30" - camera_elevation=".2"> - <param_alpha - multiply_blend="true" - tga_file="jacket_length_upper_alpha.tga" - domain="0.01" /> - </param> - - <param - id="622" - group="1" - wearable="jacket" - edit_group="jacket" - name="open upper" - label_min="closed" - label_max="open" - value_min="0" - value_max="1" - value_default=".8" - camera_distance="1.2" - camera_angle="30" - camera_elevation=".2"> - <param_alpha - multiply_blend="true" - tga_file="jacket_open_upper_alpha.tga" - domain="0.01" /> - </param> - </layer> - - <layer - name="upper alpha" - visibility_mask="TRUE"> - <texture - local_texture="upper_alpha" /> - </layer> - - </layer_set> - -<!-- =========================================================== --> - <layer_set - body_region="lower_body" - width="512" - height="512"> - <layer - name="lower body bump base" - fixed_color = "128,128,128,255" - render_pass="bump"> - </layer> - <layer - name="base_lowerbody bump" - render_pass="bump"> - <texture - tga_file="bump_lowerbody_base.tga" - file_is_mask="FALSE" /> - - <param - id="878" - group="1" - wearable="skin" - edit_group="driven" - edit_group_order="20" - name="Bump upperdef" - value_min="0" - value_max="1"> - <param_alpha - domain="0" /> - </param> - </layer> - - <layer - name="base" - global_color="skin_color"> - <texture - tga_file="body_skingrain.tga" /> - </layer> - - <layer - name="shadow"> - <texture - tga_file="lowerbody_shading_alpha.tga" - file_is_mask="TRUE" /> - - <param - id="160" - group="1" - name="Shading" - wearable="pants" - value_min="0" - value_max="1"> - <param_color> - <value - color="0, 0, 0, 0" /> - - <value - color="0, 0, 0, 128" /> - </param_color> - </param> - </layer> - - <layer - name="highlight"> - <texture - tga_file="lowerbody_highlights_alpha.tga" - file_is_mask="TRUE" /> - - <param - id="161" - group="1" - name="Shading" - wearable="skin" - value_min="0" - value_max="1"> - <param_color> - <value - color="255, 255, 255, 0" /> - - <value - color="255, 255, 255, 64" /> - </param_color> - </param> - </layer> - - <layer - name="toenails"> - <texture - tga_file="lowerbody_color.tga" /> - </layer> - - <layer - name="lower_bodypaint"> - <texture - local_texture="lower_bodypaint" /> - </layer> - - <layer - name="freckles lower" - fixed_color="120,47,20,128"> - <param - id="777" - group="1" - name="freckles lower" - wearable="skin" - value_min="0" - value_max="1"> - <param_alpha - tga_file="bodyfreckles_alpha.tga" - skip_if_zero="true" - domain="0.6" /> - </param> - </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"> - <texture - local_texture="lower_underpants" - local_texture_alpha_only="true" /> - - <param - id="1055" - group="1" - wearable="underpants" - edit_group="underpants" - name="Pants Length" - value_min="0" - value_max="1" - value_default=".3"> - <param_alpha - tga_file="pants_length_alpha.tga" - domain="0.01" /> - </param> - - <param - id="1057" - group="1" - wearable="underpants" - edit_group="underpants" - name="Pants Waist" - value_min="0" - value_max="1" - value_default=".8"> - <param_alpha - tga_file="pants_waist_alpha.tga" - domain="0.05" /> - </param> - </layer> - - <layer - name="lower_underpants"> - <texture - local_texture="lower_underpants" /> - - <param - id="824" - group="0" - wearable="underpants" - edit_group="colorpicker" - name="underpants_red" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="255, 0, 0, 255" /> - </param_color> - </param> - - <param - id="825" - group="0" - wearable="underpants" - edit_group="colorpicker" - name="underpants_green" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 255, 0, 255" /> - </param_color> - </param> - - <param - id="826" - group="0" - wearable="underpants" - edit_group="colorpicker" - name="underpants_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 0, 255, 255" /> - </param_color> - </param> - - <param - id="1054" - group="1" - wearable="underpants" - edit_group="driven" - name="Pants Length" - value_min="0" - value_max="1" - value_default=".3" - camera_distance="1.2" - camera_angle="30" - camera_elevation="-.3"> - <param_alpha - tga_file="pants_length_alpha.tga" - domain="0.01" /> - </param> - - <param - id="1056" - group="1" - wearable="underpants" - edit_group="driven" - name="Pants Waist" - value_min="0" - value_max="1" - value_default=".8"> - <param_alpha - tga_file="pants_waist_alpha.tga" - domain="0.05" /> - </param> - </layer> - - <layer - name="lower_socks bump" - render_pass="bump" - fixed_color="128,128,128,255"> - <texture - local_texture="lower_socks" - local_texture_alpha_only="true" /> - - <param - id="1051" - group="1" - wearable="socks" - edit_group="driven" - name="Socks Length bump" - value_min="0" - value_max="1" - value_default="0.35"> - <param_alpha - tga_file="shoe_height_alpha.tga" - domain="0.01" /> - </param> - </layer> - - <layer - name="lower_socks"> - <texture - local_texture="lower_socks" /> - - <param - id="818" - group="0" - wearable="socks" - edit_group="colorpicker" - name="socks_red" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="255, 0, 0, 255" /> - </param_color> - </param> - - <param - id="819" - group="0" - wearable="socks" - edit_group="colorpicker" - name="socks_green" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 255, 0, 255" /> - </param_color> - </param> - - <param - id="820" - group="0" - wearable="socks" - edit_group="colorpicker" - name="socks_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 0, 255, 255" /> - </param_color> - </param> - - <param - id="1050" - group="1" - wearable="socks" - edit_group="driven" - name="Socks Length bump" - value_min="0" - value_max="1" - value_default="0.35"> - <param_alpha - tga_file="shoe_height_alpha.tga" - domain="0.01" /> - </param> - </layer> - - <layer - name="lower_shoes bump" - render_pass="bump" - fixed_color="128,128,128,255"> - <texture - local_texture="lower_shoes" - local_texture_alpha_only="true" /> - - <param - id="1053" - group="1" - wearable="shoes" - edit_group="driven" - name="Shoe Height bump" - value_min="0" - value_max="1" - value_default="0.1"> - <param_alpha - tga_file="shoe_height_alpha.tga" - domain="0.01" /> - </param> - </layer> - - <layer - name="lower_shoes"> - <texture - local_texture="lower_shoes" /> - - <param - id="812" - group="0" - wearable="shoes" - edit_group="colorpicker" - name="shoes_red" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="255, 0, 0, 255" /> - </param_color> - </param> - - <param - id="813" - group="0" - wearable="shoes" - edit_group="colorpicker" - name="shoes_green" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 255, 0, 255" /> - </param_color> - </param> - - <param - id="817" - group="0" - wearable="shoes" - edit_group="colorpicker" - name="shoes_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 0, 255, 255" /> - </param_color> - </param> - - <param - id="1052" - group="1" - wearable="shoes" - edit_group="driven" - name="Shoe Height" - value_min="0" - value_max="1" - value_default="0.1"> - <param_alpha - tga_file="shoe_height_alpha.tga" - domain="0.01" /> - </param> - </layer> - - <layer - name="lower_clothes_shadow"> - <texture - local_texture="lower_pants" /> - - <param - id="913" - group="1" - edit_group="driven" - wearable="pants" - name="Lower Clothes Shading" - value_min="0" - value_max="1" - value_default="0"> - <param_color> - <value - color="0, 0, 0, 0" /> - - <value - color="0, 0, 0, 80" /> - </param_color> - </param> - - <param - id="914" - group="1" - edit_group="driven" - wearable="pants" - name="Waist Height Shadow" - value_min="0.02" - value_max="1"> - <param_alpha - tga_file="pants_waist_alpha.tga" - skip_if_zero="true" - domain="0.04" /> - </param> - - <param - id="915" - group="1" - edit_group="driven" - wearable="pants" - name="Pants Length Shadow" - value_min="0.02" - value_max="1"> - <param_alpha - tga_file="pants_length_alpha.tga" - skip_if_zero="true" - domain="0.03" /> - </param> - </layer> - - <layer - name="lower_pants base bump" - render_pass="bump" - fixed_color="128,128,128,255"> - <texture - local_texture="lower_pants" - local_texture_alpha_only="true" /> - - <param - id="1035" - group="1" - edit_group="driven" - wearable="pants" - name="Waist Height Cloth" - value_min="0" - value_max="1"> - <param_alpha - tga_file="pants_waist_alpha.tga" - domain="0.05" /> - </param> - - <param - id="1036" - group="1" - edit_group="driven" - wearable="pants" - name="Pants Length Cloth" - value_min="0" - value_max="1"> - <param_alpha - tga_file="pants_length_alpha.tga" - domain="0.01" /> - </param> - </layer> - - <layer - name="lower_pants bump" - render_pass="bump"> - <texture - tga_file="bump_pants_wrinkles.tga" /> - - <texture - local_texture="lower_pants" - local_texture_alpha_only="true" /> - - <param - id="869" - group="0" - wearable="pants" - edit_group="pants" - edit_group_order="6" - name="Pants Wrinkles" - value_min="0" - value_max="1" - value_default="0"> - <param_color> - <value - color="255, 255, 255, 0" /> - - <value - color="255, 255, 255, 255" /> - </param_color> - </param> - - <param - id="1017" - group="1" - edit_group="driven" - wearable="pants" - name="Waist Height Cloth" - value_min="0" - value_max="1"> - <param_alpha - tga_file="pants_waist_alpha.tga" - domain="0.05" /> - </param> - - <param - id="1018" - group="1" - edit_group="driven" - wearable="pants" - name="Pants Length Cloth" - value_min="0" - value_max="1"> - <param_alpha - tga_file="pants_length_alpha.tga" - domain="0.01" /> - </param> - </layer> - - <layer - name="lower_pants"> - <texture - local_texture="lower_pants" /> - - <param - id="806" - group="0" - wearable="pants" - edit_group="colorpicker" - name="pants_red" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="255, 0, 0, 255" /> - </param_color> - </param> - - <param - id="807" - group="0" - wearable="pants" - edit_group="colorpicker" - name="pants_green" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 255, 0, 255" /> - </param_color> - </param> - - <param - id="808" - group="0" - wearable="pants" - edit_group="colorpicker" - name="pants_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 0, 255, 255" /> - </param_color> - </param> - - <param - id="614" - group="1" - edit_group="driven" - wearable="pants" - name="Waist Height Cloth" - value_min="0" - value_max="1" - value_default=".8"> - <param_alpha - tga_file="pants_waist_alpha.tga" - domain="0.05" /> - </param> - - <param - id="615" - group="1" - edit_group="driven" - wearable="pants" - name="Pants Length Cloth" - value_min="0" - value_max="1" - value_default=".8"> - <param_alpha - tga_file="pants_length_alpha.tga" - domain="0.01" /> - </param> - </layer> - - <layer - name="lower_jacket base bump" - render_pass="bump" - fixed_color="128,128,128,255"> - <texture - local_texture="lower_jacket" - local_texture_alpha_only="true" /> - - <param - id="1033" - group="1" - wearable="jacket" - edit_group="driven" - name="jacket bottom length lower bump" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="false" - tga_file="jacket_length_lower_alpha.tga" - domain="0.01" /> - </param> - - <param - id="1034" - group="1" - wearable="jacket" - edit_group="driven" - name="jacket open lower bump" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="jacket_open_lower_alpha.tga" - domain="0.01" /> - </param> - </layer> - - <layer - name="lower_jacket bump" - render_pass="bump"> - <texture - tga_file="bump_pants_wrinkles.tga" /> - - <texture - local_texture="lower_jacket" - local_texture_alpha_only="true" /> - - <param - id="876" - group="1" - wearable="jacket" - name="jacket upper Wrinkles" - value_min="0" - value_max="1" - value_default="0"> - <param_color> - <value - color="255, 255, 255, 0" /> - - <value - color="255, 255, 255, 255" /> - </param_color> - </param> - - <param - id="1027" - group="1" - wearable="jacket" - edit_group="driven" - name="jacket bottom length lower bump" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="false" - tga_file="jacket_length_lower_alpha.tga" - domain="0.01" /> - </param> - - <param - id="1028" - group="1" - wearable="jacket" - edit_group="driven" - name="jacket open lower bump" - value_min="0" - value_max="1"> - <param_alpha - multiply_blend="true" - tga_file="jacket_open_lower_alpha.tga" - domain="0.01" /> - </param> - </layer> - - <layer - name="lower_jacket"> - <texture - local_texture="lower_jacket" /> - - <param - id="809" - group="1" - edit_group="colorpicker_driven" - wearable="jacket" - name="lower_jacket_red" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="255, 0, 0, 255" /> - </param_color> - </param> - - <param - id="810" - group="1" - edit_group="colorpicker_driven" - wearable="jacket" - name="lower_jacket_green" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 255, 0, 255" /> - </param_color> - </param> - - <param - id="811" - group="1" - edit_group="colorpicker_driven" - wearable="jacket" - name="lower_jacket_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 0, 255, 255" /> - </param_color> - </param> - - <param - id="621" - group="1" - wearable="jacket" - edit_group="jacket" - name="bottom length lower" - label_min="hi cut" - label_max="low cut" - value_min="0" - value_max="1" - value_default=".8" - camera_distance="1.2" - camera_angle="30" - camera_elevation=".2"> - <param_alpha - multiply_blend="false" - tga_file="jacket_length_lower_alpha.tga" - domain="0.01" /> - </param> - - <param - id="623" - group="1" - wearable="jacket" - edit_group="jacket" - name="open lower" - label_min="open" - label_max="closed" - value_min="0" - value_max="1" - value_default=".8" - camera_distance="1.2" - camera_angle="30" - camera_elevation=".2"> - <param_alpha - multiply_blend="true" - tga_file="jacket_open_lower_alpha.tga" - domain="0.01" /> - </param> - </layer> - - <layer - name="lower alpha" - visibility_mask="TRUE"> - <texture - local_texture="lower_alpha" /> - </layer> - - </layer_set> - -<!-- =========================================================== --> - <layer_set - body_region="eyes" - width="128" - height="128"> - <layer - name="whites"> - <texture - tga_file="eyewhite.tga" /> - </layer> - - <layer - name="iris" - global_color="eye_color"> - <texture - local_texture="eyes_iris" /> - </layer> - - <layer - name="eyes alpha" - visibility_mask="TRUE"> - <texture - local_texture="eyes_alpha" /> - </layer> - - </layer_set> - -<!-- =========================================================== --> - <layer_set - body_region="skirt" - width="512" - height="512" - clear_alpha="false"> - <layer - name="skirt_fabric" - write_all_channels="true"> - <texture - local_texture="skirt" /> - - <param - id="921" - group="0" - wearable="skirt" - edit_group="colorpicker" - name="skirt_red" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="255, 0, 0, 255" /> - </param_color> - </param> - - <param - id="922" - group="0" - wearable="skirt" - edit_group="colorpicker" - name="skirt_green" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 255, 0, 255" /> - </param_color> - </param> - - <param - id="923" - group="0" - wearable="skirt" - edit_group="colorpicker" - name="skirt_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_color> - <value - color="0, 0, 0, 255" /> - - <value - color="0, 0, 255, 255" /> - </param_color> - </param> - </layer> - - <layer - name="skirt_fabric_alpha"> - <param - id="858" - group="0" - wearable="skirt" - edit_group="skirt" - edit_group_order="1" - name="Skirt Length" - show_simple="true" - label_min="Short" - label_max="Long" - value_min=".01" - value_max="1" - value_default=".4" - simple_percent_min="40" - simple_percent_max="100" - camera_distance="1.3" - camera_elevation="-.5" - camera_angle="30"> - <param_alpha - tga_file="skirt_length_alpha.tga" - domain="0" - multiply_blend="true" /> - </param> - - <param - id="859" - group="0" - wearable="skirt" - edit_group="skirt" - edit_group_order="4" - name="Slit Front" - label_min="Open Front" - label_max="Closed Front" - value_min="0" - value_max="1" - value_default="1" - camera_distance="1.3" - camera_elevation="-.5" - camera_angle="30"> - <param_alpha - tga_file="skirt_slit_front_alpha.tga" - multiply_blend="true" - domain="0" /> - </param> - - <param - id="860" - group="0" - wearable="skirt" - edit_group="skirt" - edit_group_order="5" - name="Slit Back" - label_min="Open Back" - label_max="Closed Back" - value_min="0" - value_max="1" - value_default="1" - camera_distance="1.3" - camera_elevation="-.5" - camera_angle="160"> - <param_alpha - tga_file="skirt_slit_back_alpha.tga" - multiply_blend="true" - domain="0" /> - </param> - - <param - id="861" - group="0" - wearable="skirt" - edit_group="skirt" - edit_group_order="6" - name="Slit Left" - label_min="Open Left" - label_max="Closed Left" - value_min="0" - value_max="1" - value_default="1" - camera_distance="1.3" - camera_elevation="-.5" - camera_angle="30"> - <param_alpha - tga_file="skirt_slit_left_alpha.tga" - multiply_blend="true" - domain="0" /> - </param> - - <param - id="862" - group="0" - wearable="skirt" - edit_group="skirt" - edit_group_order="7" - name="Slit Right" - label_min="Open Right" - label_max="Closed Right" - value_min="0" - value_max="1" - value_default="1" - camera_distance="1.3" - camera_elevation="-.5" - camera_angle="-30"> - <param_alpha - tga_file="skirt_slit_right_alpha.tga" - multiply_blend="true" - domain="0" /> - </param> - </layer> - - </layer_set> - -<!-- =========================================================== --> - <driver_parameters> - <param - id="828" - group="0" - name="Loose Upper Clothing" - label="Shirt Fit" - show_simple="true" - wearable="shirt" - edit_group="shirt" - edit_group_order="4" - label_min="Tight Shirt" - label_max="Loose Shirt" + <param + id="913" + group="1" + edit_group="driven" + wearable="pants" + name="Lower Clothes Shading" value_min="0" value_max="1" - camera_distance="1.2" - camera_angle="30" - camera_elevation=".2"> - <param_driver> - <driven - id="628" /> + value_default="0"> + <param_color> + <value + color="0, 0, 0, 0" /> - <driven - id="899" - min1="0.1" - max1="0.5" - max2="1" - min2="1" /> - </param_driver> + <value + color="0, 0, 0, 80" /> + </param_color> </param> <param - id="816" - group="0" - name="Loose Lower Clothing" - label="Pants Fit" - show_simple="true" + id="914" + group="1" + edit_group="driven" wearable="pants" - edit_group="pants" - edit_group_order="2.5" - label_min="Tight Pants" - label_max="Loose Pants" - value_min="0" - value_max="1" - camera_distance="1.8" - camera_angle="30" - camera_elevation="-.3"> - <param_driver> - <driven - id="516" /> + name="Waist Height Shadow" + value_min="0.02" + value_max="1"> + <param_alpha + tga_file="pants_waist_alpha.tga" + skip_if_zero="true" + domain="0.04" /> + </param> - <driven - id="913" - min1="0.1" - max1="0.5" - max2="1" - min2="1" /> - </param_driver> + <param + id="915" + group="1" + edit_group="driven" + wearable="pants" + name="Pants Length Shadow" + value_min="0.02" + value_max="1"> + <param_alpha + tga_file="pants_length_alpha.tga" + skip_if_zero="true" + domain="0.03" /> </param> + </layer> + + <layer + name="lower_pants base bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="lower_pants" + local_texture_alpha_only="true" /> <param - id="814" - group="0" + id="1035" + group="1" + edit_group="driven" wearable="pants" - edit_group="pants" - edit_group_order="2" - name="Waist Height" - label_min="Low" - label_max="High" + name="Waist Height Cloth" value_min="0" - value_max="1" - value_default="1" - camera_distance="1.2" - camera_angle="30" - camera_elevation="-.3"> - <param_driver> - <driven - id="614" /> + value_max="1"> + <param_alpha + tga_file="pants_waist_alpha.tga" + domain="0.05" /> + </param> - <driven - id="1017" /> + <param + id="1036" + group="1" + edit_group="driven" + wearable="pants" + name="Pants Length Cloth" + value_min="0" + value_max="1"> + <param_alpha + tga_file="pants_length_alpha.tga" + domain="0.01" /> + </param> + </layer> - <driven - id="1033" /> + <layer + name="lower_pants bump" + render_pass="bump"> + <texture + tga_file="bump_pants_wrinkles.tga" /> - <driven - id="914" - min1="0" - max1=".98" - max2="1" - min2="1" /> - </param_driver> - </param> + <texture + local_texture="lower_pants" + local_texture_alpha_only="true" /> <param - id="815" + id="869" group="0" wearable="pants" edit_group="pants" - edit_group_order="1" - name="Pants Length" - show_simple="true" - label_min="Short" - label_max="Long" - value_min="0" - value_max="1" - value_default=".8" - simple_percent_min="20" - simple_percent_max="100" - camera_distance="1.8" - camera_angle="30" - camera_elevation="-.3"> - <param_driver> - <driven - id="615" - min1="0" - max1=".9" - max2="1" - min2="1" /> - - <driven - id="1018" - min1="0" - max1=".9" - max2="1" - min2="1" /> - - <driven - id="1036" - min1="0" - max1=".9" - max2="1" - min2="1" /> - - <driven - id="793" - min1=".9" - max1="1" - max2="1" - min2="1" /> - - <driven - id="915" - min1="0" - max1=".882" - max2="1" - min2="1" /> - </param_driver> - </param> - - <param - id="800" - group="0" - wearable="shirt" - edit_group="shirt" - edit_group_order="1" - name="Sleeve Length" - show_simple="true" - label_min="Short" - label_max="Long" + edit_group_order="6" + name="Pants Wrinkles" value_min="0" value_max="1" - value_default=".89" - simple_percent_min="15" - simple_percent_max="100" - camera_distance="1.2" - camera_angle="30" - camera_elevation=".2"> - <param_driver> - <driven - id="600" /> - - <driven - id="1013" /> - - <driven - id="1029" /> + value_default="0"> + <param_color> + <value + color="255, 255, 255, 0" /> - <driven - id="900" - min1="0" - max1="1" - max2="1" - min2="1" /> - </param_driver> + <value + color="255, 255, 255, 255" /> + </param_color> </param> <param - id="801" - group="0" - wearable="shirt" - edit_group="shirt" - edit_group_order="2" - name="Shirt Bottom" - label_min="Short" - label_max="Long" + id="1017" + group="1" + edit_group="driven" + wearable="pants" + name="Waist Height Cloth" value_min="0" - value_max="1" - value_default="1" - camera_distance="1.2" - camera_angle="30" - camera_elevation=".2"> - <param_driver> - <driven - id="601" /> - - <driven - id="1014" /> - - <driven - id="1030" /> + value_max="1"> + <param_alpha + tga_file="pants_waist_alpha.tga" + domain="0.05" /> + </param> - <driven - id="901" - min1="0" - max1=".98" - max2="1" - min2="1" /> - </param_driver> + <param + id="1018" + group="1" + edit_group="driven" + wearable="pants" + name="Pants Length Cloth" + value_min="0" + value_max="1"> + <param_alpha + tga_file="pants_length_alpha.tga" + domain="0.01" /> </param> + </layer> + + <layer + name="lower_pants"> + <texture + local_texture="lower_pants" /> <param - id="802" + id="806" group="0" - wearable="shirt" - edit_group="shirt" - edit_group_order="3" - name="Collar Front" - show_simple="true" - label_min="Low" - label_max="High" + wearable="pants" + edit_group="colorpicker" + name="pants_red" value_min="0" value_max="1" - value_default=".78" - simple_percent_min="40" - simple_percent_max="100" - camera_distance="1.2" - camera_angle="15" - camera_elevation=".2"> - <param_driver> - <driven - id="602" /> - - <driven - id="1015" /> - - <driven - id="1031" /> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - <driven - id="902" - min1="0" - max1=".98" - max2="1" - min2="1" /> - </param_driver> + <value + color="255, 0, 0, 255" /> + </param_color> </param> <param - id="781" + id="807" group="0" - wearable="shirt" - edit_group="shirt" - edit_group_order="3.1" - name="Collar Back" - label_min="Low" - label_max="High" + wearable="pants" + edit_group="colorpicker" + name="pants_green" value_min="0" value_max="1" - value_default=".78" - camera_distance="1.2" - camera_angle="195" - camera_elevation=".2"> - <param_driver> - <driven - id="778" /> - - <driven - id="1016" /> - - <driven - id="1032" /> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - <driven - id="903" - min1="0" - max1=".98" - max2="1" - min2="1" /> - </param_driver> + <value + color="0, 255, 0, 255" /> + </param_color> </param> <param - id="150" + id="808" group="0" - wearable="skin" - edit_group="skin_bodydetail" - name="Body Definition" - label_min="Less" - label_max="More" + wearable="pants" + edit_group="colorpicker" + name="pants_blue" value_min="0" value_max="1" - value_default="0" - camera_distance="1.4" - camera_elevation="-.2"> - <param_driver> - <driven - id="125" /> - - <driven - id="126" /> - - <driven - id="160" /> - - <driven - id="161" /> - - <driven - id="874" /> - - <driven - id="878" /> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - </param_driver> + <value + color="0, 0, 255, 255" /> + </param_color> </param> <param - id="775" - group="0" - wearable="skin" - edit_group="skin_bodydetail" - name="Body Freckles" - label_min="Less Freckles" - label_max="More Freckles" + id="614" + group="1" + edit_group="driven" + wearable="pants" + name="Waist Height Cloth" value_min="0" value_max="1" - value_default="0" - camera_distance="1.4" - camera_elevation="-.2"> - <param_driver> - <driven - id="776" /> - - <driven - id="777" /> - </param_driver> + value_default=".8"> + <param_alpha + tga_file="pants_waist_alpha.tga" + domain="0.05" /> </param> <param - id="162" - group="0" - wearable="skin" - edit_group="skin_facedetail" - edit_group_order="1" - name="Facial Definition" - label_min="Less" - label_max="More" + id="615" + group="1" + edit_group="driven" + wearable="pants" + name="Pants Length Cloth" value_min="0" value_max="1" - camera_distance=".3" - camera_elevation=".07" - value_default="0"> - <param_driver> - <driven - id="158" /> + value_default=".8"> + <param_alpha + tga_file="pants_length_alpha.tga" + domain="0.01" /> + </param> + </layer> - <driven - id="159" /> + <layer + name="lower_jacket base bump" + render_pass="bump" + fixed_color="128,128,128,255"> + <texture + local_texture="lower_jacket" + local_texture_alpha_only="true" /> - <driven - id="873" /> - </param_driver> + <param + id="1033" + group="1" + wearable="jacket" + edit_group="driven" + cross_wearable="true" + name="jacket bottom length lower bump" + value_min="0" + value_max="1"> + <param_alpha + multiply_blend="false" + tga_file="jacket_length_lower_alpha.tga" + domain="0.01" /> </param> <param - id="163" - group="0" - wearable="skin" - edit_group="skin_facedetail" - edit_group_order="3" - name="wrinkles" - label_min="Less" - label_max="More" + id="1034" + group="1" + wearable="jacket" + edit_group="driven" + name="jacket open lower bump" value_min="0" - value_max="1" - camera_distance=".3" - camera_elevation=".07" - value_default="0"> - <param_driver> -<!--<driven - id="128" />--> - <driven - id="118" /> - </param_driver> + value_max="1"> + <param_alpha + multiply_blend="true" + tga_file="jacket_open_lower_alpha.tga" + domain="0.01" /> </param> + </layer> + + <layer + name="lower_jacket bump" + render_pass="bump"> + <texture + tga_file="bump_pants_wrinkles.tga" /> + + <texture + local_texture="lower_jacket" + local_texture_alpha_only="true" /> + <param - id="505" - group="0" - wearable="shape" - edit_group="shape_mouth" - edit_group_order="3" - name="Lip Thickness" - label_min="Thin Lips" - label_max="Fat Lips" + id="876" + group="1" + wearable="jacket" + name="jacket upper Wrinkles" value_min="0" value_max="1" - value_default=".5" - camera_distance=".3" - camera_elevation=".04" - camera_angle="20"> - <param_driver> - <driven - id="26" - min1="0" - max1="0" - max2="0" - min2=".5" /> + value_default="0"> + <param_color> + <value + color="255, 255, 255, 0" /> - <driven - id="28" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> + <value + color="255, 255, 255, 255" /> + </param_color> </param> <param - id="799" - group="0" - wearable="shape" - edit_group="shape_mouth" - edit_group_order="3.2" - name="Lip Ratio" - label="Lip Ratio" - show_simple="true" - label_min="More Upper Lip" - label_max="More Lower Lip" + id="1027" + group="1" + wearable="jacket" + edit_group="driven" + name="jacket bottom length lower bump" value_min="0" - value_max="1" - value_default=".5" - camera_distance=".3" - camera_elevation=".04" - camera_angle="20"> - <param_driver> - <driven - id="797" - min1="0" - max1="0" - max2="0" - min2=".5" /> - - <driven - id="798" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> + value_max="1"> + <param_alpha + multiply_blend="false" + tga_file="jacket_length_lower_alpha.tga" + domain="0.01" /> </param> <param - id="155" - group="0" - wearable="shape" - edit_group="shape_mouth" - edit_group_order="1" - name="Lip Width" - label="Lip Width" - label_min="Narrow Lips" - label_max="Wide Lips" - show_simple="true" - value_min="-0.9" - value_max="1.3" - camera_distance=".3" - camera_elevation=".04" - value_default="0"> - <param_driver> - <driven - id="29" /> - - <driven - id="30" /> - </param_driver> + id="1028" + group="1" + wearable="jacket" + edit_group="driven" + name="jacket open lower bump" + value_min="0" + value_max="1"> + <param_alpha + multiply_blend="true" + tga_file="jacket_open_lower_alpha.tga" + domain="0.01" /> </param> + </layer> + + <layer + name="lower_jacket"> + <texture + local_texture="lower_jacket" /> <param - id="196" - group="0" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="2" - name="Eye Spacing" - label="Eye Spacing" - label_min="Close Set Eyes" - label_max="Far Set Eyes" - show_simple="true" - value_min="-2" + id="809" + group="1" + edit_group="colorpicker_driven" + wearable="jacket" + name="lower_jacket_red" + value_min="0" value_max="1" - value_default="0" - camera_elevation=".1" - camera_distance=".35" - camera_angle="5"> - <param_driver> - <driven - id="194" /> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - <driven - id="195" /> - </param_driver> + <value + color="255, 0, 0, 255" /> + </param_color> </param> <param - id="769" - group="0" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="4.5" - name="Eye Depth" - label_min="Sunken Eyes" - label_max="Bugged Eyes" + id="810" + group="1" + edit_group="colorpicker_driven" + wearable="jacket" + name="lower_jacket_green" value_min="0" value_max="1" - value_default=".5" - camera_elevation=".1" - camera_distance=".3" - camera_angle="75"> - <param_driver> - <driven - id="767" /> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - <driven - id="768" /> - </param_driver> + <value + color="0, 255, 0, 255" /> + </param_color> </param> <param - id="198" - group="0" - wearable="shoes" - edit_group="shoes" - edit_group_order="2" - name="Heel Height" - label_min="Low Heels" - label_max="High Heels" + id="811" + group="1" + edit_group="colorpicker_driven" + wearable="jacket" + name="lower_jacket_blue" value_min="0" value_max="1" - value_default="0" - camera_angle="45" - camera_distance=".8" - camera_elevation="-1"> - <param_driver> - <driven - id="197" /> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - <driven - id="500" /> - </param_driver> + <value + color="0, 0, 255, 255" /> + </param_color> </param> <param - id="513" - group="0" - wearable="shoes" - edit_group="shoes" - edit_group_order="3" - name="Heel Shape" - label_min="Pointy Heels" - label_max="Thick Heels" - value_min="0" - value_max="1" - value_default=".5" - camera_angle="45" - camera_distance="1.5" - camera_elevation="-1"> - <param_driver> - <driven - id="509" - min1="0" - max1="0" - max2="0" - min2=".5" /> - - <driven - id="510" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> - - <param - id="514" - group="0" - wearable="shoes" - edit_group="shoes" - edit_group_order="4" - name="Toe Shape" - label_min="Pointy" - label_max="Square" - value_min="0" - value_max="1" - value_default=".5" - camera_angle="5" - camera_distance=".8" - camera_elevation="-.8"> - <param_driver> - <driven - id="511" - min1="0" - max1="0" - max2="0" - min2=".5" /> - - <driven - id="512" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> - - <param - id="503" - group="0" - wearable="shoes" - edit_group="shoes" - edit_group_order="6" - name="Platform Height" - label_min="Low Platforms" - label_max="High Platforms" + id="621" + group="1" + wearable="jacket" + edit_group="jacket" + name="bottom length lower" + label_min="hi cut" + label_max="low cut" value_min="0" value_max="1" - value_default="0" - camera_angle="45" - camera_distance=".5" - camera_elevation="-1"> - <param_driver> - <driven - id="501" /> - - <driven - id="502" /> - </param_driver> + value_default=".8" + camera_distance="1.2" + camera_angle="30" + camera_elevation=".2"> + <param_alpha + multiply_blend="false" + tga_file="jacket_length_lower_alpha.tga" + domain="0.01" /> </param> <param - id="193" - group="0" - wearable="shape" - edit_group="shape_head" - edit_group_order="3" - name="Head Shape" - label="Head Shape" - label_min="More Square" - label_max="More Round" - show_simple="true" - value_min="0" - value_max="1" - value_default=".5" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_driver> - <driven - id="188" - min1="0" - max1="0" - max2="0" - min2=".5" /> - - <driven - id="642" - min1="0" - max1="0" - max2="0" - min2=".5" /> - - <driven - id="189" - min1=".5" - max1="1" - max2="1" - min2="1" /> - - <driven - id="643" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> - - <param - id="157" - group="0" - wearable="shape" - edit_group="shape_torso" - edit_group_order="13" - name="Belly Size" - label_min="Small" - label_max="Big" + id="623" + group="1" + wearable="jacket" + edit_group="jacket" + name="open lower" + label_min="open" + label_max="closed" value_min="0" value_max="1" - value_default="0" - camera_distance="1.4" + value_default=".8" + camera_distance="1.2" camera_angle="30" camera_elevation=".2"> - <param_driver> - <driven - id="104" /> + <param_alpha + multiply_blend="true" + tga_file="jacket_open_lower_alpha.tga" + domain="0.01" /> + </param> + </layer> - <driven - id="156" /> + <layer + name="lower alpha" + visibility_mask="TRUE"> + <texture + local_texture="lower_alpha" /> + </layer> - <driven - id="849" /> - </param_driver> - </param> + </layer_set> - <param - id="637" - group="0" - wearable="shape" - edit_group="shape_body" - edit_group_order="3" - name="Body Fat" - label_min="Less Body Fat" - label_max="More Body Fat" - value_min="0" - value_max="1" - value_default="0" - camera_distance="1.8"> - <param_driver> - <driven - id="633" /> + <!-- =========================================================== --> + <layer_set + body_region="eyes" + width="128" + height="128"> + <layer + name="whites"> + <texture + tga_file="eyewhite.tga" /> + </layer> - <driven - id="634" /> + <layer + name="iris" + global_color="eye_color"> + <texture + local_texture="eyes_iris" /> + </layer> + + <layer + name="eyes alpha" + visibility_mask="TRUE"> + <texture + local_texture="eyes_alpha" /> + </layer> - <driven - id="635" /> + </layer_set> - <driven - id="851" /> - </param_driver> - </param> + <!-- =========================================================== --> + <layer_set + body_region="skirt" + width="512" + height="512" + clear_alpha="false"> + <layer + name="skirt_fabric" + write_all_channels="true"> + <texture + local_texture="skirt" /> <param - id="130" + id="921" group="0" - wearable="hair" - edit_group="hair_style" - edit_group_order="8" - name="Front Fringe" - label_min="Short" - label_max="Long" + wearable="skirt" + edit_group="colorpicker" + name="skirt_red" value_min="0" value_max="1" - value_default=".45" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_driver> - <driven - id="144" - min1="0" - max1="0" - max2="0" - min2=".5" /> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - <driven - id="145" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> + <value + color="255, 0, 0, 255" /> + </param_color> </param> <param - id="131" + id="922" group="0" - wearable="hair" - edit_group="hair_style" - edit_group_order="9" - name="Side Fringe" - label_min="Short" - label_max="Long" - value_min="0" - value_max="1" - value_default=".5" - camera_elevation=".1" - camera_distance=".5" - camera_angle="90"> - <param_driver> - <driven - id="146" - min1="0" - max1="0" - max2="0" - min2=".5" /> - - <driven - id="147" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> - - <param - id="132" - group="0" - wearable="hair" - edit_group="hair_style" - edit_group_order="10" - name="Back Fringe" - label_min="Short" - label_max="Long" + wearable="skirt" + edit_group="colorpicker" + name="skirt_green" value_min="0" value_max="1" - value_default=".39" - camera_elevation=".1" - camera_distance=".5" - camera_angle="160"> - <param_driver> - <driven - id="148" - min1="0" - max1="0" - max2="0" - min2=".5" /> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - <driven - id="149" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> + <value + color="0, 255, 0, 255" /> + </param_color> </param> <param - id="133" + id="923" group="0" - wearable="hair" - edit_group="hair_style" - edit_group_order="2" - name="Hair Front" - label_min="Short" - label_max="Long" + wearable="skirt" + edit_group="colorpicker" + name="skirt_blue" value_min="0" value_max="1" - value_default=".25" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_driver> - <driven - id="172" - min1="0" - max1="0" - max2="0" - min2=".5" /> + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> - <driven - id="171" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> + <value + color="0, 0, 255, 255" /> + </param_color> </param> + </layer> + <layer + name="skirt_fabric_alpha"> <param - id="134" + id="858" group="0" - wearable="hair" - edit_group="hair_style" - edit_group_order="3" - name="Hair Sides" - label_min="Short" - label_max="Long" - value_min="0" - value_max="1" - value_default=".5" - camera_elevation=".1" - camera_distance=".5" - camera_angle="90"> - <param_driver> - <driven - id="174" - min1="0" - max1="0" - max2="0" - min2=".5" /> - - <driven - id="173" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> - - <param - id="135" - group="0" - wearable="hair" - edit_group="hair_style" - edit_group_order="4" - name="Hair Back" - show_simple="true" + wearable="skirt" + edit_group="skirt" + edit_group_order="1" + name="Skirt Length" + show_simple="true" label_min="Short" label_max="Long" - value_min="0" + value_min=".01" value_max="1" - value_default=".55" - camera_elevation="-.1" - camera_distance=".8" - camera_angle="160"> - <param_driver> - <driven - id="176" - min1="0" - max1="0" - max2="0" - min2=".5" /> - - <driven - id="175" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> + value_default=".4" + simple_percent_min="40" + simple_percent_max="100" + camera_distance="1.3" + camera_elevation="-.5" + camera_angle="30"> + <param_alpha + tga_file="skirt_length_alpha.tga" + domain="0" + multiply_blend="true" /> </param> <param - id="136" - group="0" - wearable="hair" - edit_group="hair_style" - edit_group_order="11.5" - name="Hair Sweep" - label_min="Sweep Forward" - label_max="Sweep Back" - value_min="0" - value_max="1" - value_default=".5" - camera_elevation=".1" - camera_distance=".5" - camera_angle="90"> - <param_driver> - <driven - id="179" - min1="0" - max1="0" - max2="0" - min2=".5" /> - - <driven - id="178" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> - - <param - id="137" - group="0" - wearable="hair" - edit_group="hair_style" - edit_group_order="16" - name="Hair Tilt" - label_min="Left" - label_max="Right" - value_min="0" - value_max="1" - value_default=".5" - camera_elevation=".1" - camera_distance=".5" - camera_angle="0"> - <param_driver> - <driven - id="190" - min1="0" - max1="0" - max2="0" - min2=".5" /> - - <driven - id="191" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> - - <param - id="608" + id="859" group="0" - wearable="jacket" - edit_group="jacket" - edit_group_order="2" - name="bottom length lower" - label="Jacket Length" - label_min="Short" - label_max="Long" + wearable="skirt" + edit_group="skirt" + edit_group_order="4" + name="Slit Front" + label_min="Open Front" + label_max="Closed Front" value_min="0" value_max="1" - value_default=".8" - camera_distance="1.4" - camera_angle="30" - camera_elevation=".2"> - <param_driver> - <driven - id="620" /> - - <driven - id="1025" /> - - <driven - id="1037" /> - - <driven - id="621" /> - - <driven - id="1027" /> - - <driven - id="1033" /> - </param_driver> + value_default="1" + camera_distance="1.3" + camera_elevation="-.5" + camera_angle="30"> + <param_alpha + tga_file="skirt_slit_front_alpha.tga" + multiply_blend="true" + domain="0" /> </param> <param - id="609" + id="860" group="0" - wearable="jacket" - edit_group="jacket" - edit_group_order="4" - name="open jacket" - label="Open Front" - label_min="Open" - label_max="Closed" + wearable="skirt" + edit_group="skirt" + edit_group_order="5" + name="Slit Back" + label_min="Open Back" + label_max="Closed Back" value_min="0" value_max="1" - value_default=".2" - camera_distance="1.4" - camera_angle="30" - camera_elevation=".2"> - <param_driver> - <driven - id="622" /> - - <driven - id="1026" /> - - <driven - id="1038" /> - - <driven - id="623" /> - - <driven - id="1028" /> - - <driven - id="1034" /> - </param_driver> + value_default="1" + camera_distance="1.3" + camera_elevation="-.5" + camera_angle="160"> + <param_alpha + tga_file="skirt_slit_back_alpha.tga" + multiply_blend="true" + domain="0" /> </param> <param - id="105" + id="861" group="0" - sex="female" - wearable="shape" - edit_group="shape_torso" + wearable="skirt" + edit_group="skirt" edit_group_order="6" - name="Breast Size" - label_min="Small" - label_max="Large" + name="Slit Left" + label_min="Open Left" + label_max="Closed Left" value_min="0" value_max="1" - value_default=".5" - camera_elevation=".3" - camera_distance="1.2" + value_default="1" + camera_distance="1.3" + camera_elevation="-.5" camera_angle="30"> - <param_driver> - <driven - id="843" - min1="0" - max1="0" - max2="0" - min2=".01" /> - - <driven - id="627" - min1="0" - max1="0.01" - max2="0.01" - min2=".5" /> - - <driven - id="626" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> - - <param - id="629" - group="0" - wearable="shape" - edit_group="shape_head" - edit_group_order="6" - name="Forehead Angle" - label_min="More Vertical" - label_max="More Sloped" - value_min="0" - value_max="1" - value_default=".5" - camera_elevation=".1" - camera_distance=".5" - camera_angle="70"> - <param_driver> - <driven - id="630" - min1="0" - max1="0" - max2="0" - min2=".5" /> - - <driven - id="644" - min1="0" - max1="0" - max2="0" - min2=".5" /> - - <driven - id="631" - min1=".5" - max1="1" - max2="1" - min2="1" /> - - <driven - id="645" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> - - <param - id="646" - group="0" - name="Egg_Head" - label="Egg Head" - wearable="shape" - edit_group="shape_head" - edit_group_order="4" - label_min="Chin Heavy" - label_max="Forehead Heavy" - show_simple="true" - value_min="-1.3" - value_max="1" - value_default="0" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_driver> - <driven - id="640" /> - - <driven - id="186" /> - </param_driver> - </param> - - <param - id="647" - group="0" - name="Squash_Stretch_Head" - label="Head Stretch" - wearable="shape" - edit_group="shape_head" - edit_group_order="2" - show_simple="true" - label_min="Squash Head" - label_max="Stretch Head" - value_min="-0.5" - value_max="1" - value_default="0" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_driver> - <driven - id="641" /> - - <driven - id="187" /> - </param_driver> + <param_alpha + tga_file="skirt_slit_left_alpha.tga" + multiply_blend="true" + domain="0" /> </param> <param - id="649" - group="0" - sex="female" - wearable="shape" - edit_group="shape_torso" - edit_group_order="1.1" - name="Torso Muscles" - label="Torso Muscles" - show_simple="true" - label_min="Less Muscular" - label_max="More Muscular" - value_min="0" - value_max="1" - value_default=".5" - camera_elevation=".1" - camera_distance="1" - camera_angle="15"> - <param_driver> - <driven - id="648" - min1="0" - max1="0" - max2="0" - min2=".5" /> - - <driven - id="106" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> - - <param - id="678" + id="862" group="0" - sex="male" - wearable="shape" - edit_group="shape_torso" - edit_group_order="1" - name="Torso Muscles" - show_simple="true" - label_min="Less Muscular" - label_max="More Muscular" - value_min="0" - value_max="1" - value_default=".5" - camera_elevation=".1" - camera_distance="1.2" - camera_angle="0"> - <param_driver> - <driven - id="677" - min1="0" - max1="0" - max2="0" - min2=".5" /> - - <driven - id="106" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> - - <param - id="652" - group="0" - wearable="shape" - edit_group="shape_legs" - edit_group_order="1" - name="Leg Muscles" - label_min="Less Muscular" - label_max="More Muscular" - show_simple="true" + wearable="skirt" + edit_group="skirt" + edit_group_order="7" + name="Slit Right" + label_min="Open Right" + label_max="Closed Right" value_min="0" value_max="1" - value_default=".5" + value_default="1" camera_distance="1.3" camera_elevation="-.5" - camera_angle="15"> - <param_driver> - <driven - id="651" - min1="0" - max1="0" - max2="0" - min2=".5" /> - - <driven - id="152" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> - - <param - id="80" - name="male" - group="0" - edit_group="dummy" - wearable="shape" - value_min="0" - value_max="1"> - <param_driver> - <driven - id="32" /> + camera_angle="-30"> + <param_alpha + tga_file="skirt_slit_right_alpha.tga" + multiply_blend="true" + domain="0" /> + </param> + </layer> - <driven - id="153" /> + </layer_set> - <driven - id="40" /> + <!-- =========================================================== --> + <driver_parameters> + <param + id="828" + group="0" + name="Loose Upper Clothing" + label="Shirt Fit" + show_simple="true" + wearable="shirt" + edit_group="shirt" + edit_group_order="4" + label_min="Tight Shirt" + label_max="Loose Shirt" + value_min="0" + value_max="1" + camera_distance="1.2" + camera_angle="30" + camera_elevation=".2"> + <param_driver> + <driven + id="628" /> + + <driven + id="899" + min1="0.1" + max1="0.5" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="100" /> + <param + id="816" + group="0" + name="Loose Lower Clothing" + label="Pants Fit" + show_simple="true" + wearable="pants" + edit_group="pants" + edit_group_order="2.5" + label_min="Tight Pants" + label_max="Loose Pants" + value_min="0" + value_max="1" + camera_distance="1.8" + camera_angle="30" + camera_elevation="-.3"> + <param_driver> + <driven + id="516" /> + + <driven + id="913" + min1="0.1" + max1="0.5" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="857" /> - </param_driver> - </param> + <param + id="814" + group="0" + wearable="pants" + edit_group="pants" + edit_group_order="2" + name="Waist Height" + label_min="Low" + label_max="High" + value_min="0" + value_max="1" + value_default="1" + camera_distance="1.2" + camera_angle="30" + camera_elevation="-.3"> + <param_driver> + <driven + id="614" /> + + <driven + id="1017" /> + + <driven + id="1033" /> + + <driven + id="914" + min1="0" + max1=".98" + max2="1" + min2="1" /> + </param_driver> + </param> - <param - id="659" - group="0" - wearable="shape" - edit_group="shape_mouth" - edit_group_order="5" - name="Mouth Corner" - label_min="Corner Down" - label_max="Corner Up" - value_min="0" - value_max="1" - value_default=".5" - camera_elevation="0" - camera_distance=".28"> - <param_driver> - <driven - id="658" - min1="0" - max1="0" - max2="0" - min2=".5" /> - - <driven - id="657" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> - - <param - id="662" - group="0" - wearable="shape" - edit_group="shape_head" - edit_group_order="5" - name="Face Shear" - label_min="Shear Right Up" - label_max="Shear Left Up" - value_min="0" - value_max="1" - value_default=".5" - camera_elevation=".1" - camera_distance=".5"> - <param_driver> - <driven - id="660" /> + <param + id="815" + group="0" + wearable="pants" + edit_group="pants" + edit_group_order="1" + name="Pants Length" + show_simple="true" + label_min="Short" + label_max="Long" + value_min="0" + value_max="1" + value_default=".8" + simple_percent_min="20" + simple_percent_max="100" + camera_distance="1.8" + camera_angle="30" + camera_elevation="-.3"> + <param_driver> + <driven + id="615" + min1="0" + max1=".9" + max2="1" + min2="1" /> + + <driven + id="1018" + min1="0" + max1=".9" + max2="1" + min2="1" /> + + <driven + id="1036" + min1="0" + max1=".9" + max2="1" + min2="1" /> + + <driven + id="793" + min1=".9" + max1="1" + max2="1" + min2="1" /> + + <driven + id="915" + min1="0" + max1=".882" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="661" /> + <param + id="800" + group="0" + wearable="shirt" + edit_group="shirt" + edit_group_order="1" + name="Sleeve Length" + show_simple="true" + label_min="Short" + label_max="Long" + value_min="0" + value_max="1" + value_default=".89" + simple_percent_min="15" + simple_percent_max="100" + camera_distance="1.2" + camera_angle="30" + camera_elevation=".2"> + <param_driver> + <driven + id="600" /> + + <driven + id="1013" /> + + <driven + id="1029" /> + + <driven + id="900" + min1="0" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="774" /> - </param_driver> - </param> + <param + id="801" + group="0" + wearable="shirt" + edit_group="shirt" + edit_group_order="2" + name="Shirt Bottom" + label_min="Short" + label_max="Long" + value_min="0" + value_max="1" + value_default="1" + camera_distance="1.2" + camera_angle="30" + camera_elevation=".2"> + <param_driver> + <driven + id="601" /> + + <driven + id="1014" /> + + <driven + id="1030" /> + + <driven + id="901" + min1="0" + max1=".98" + max2="1" + min2="1" /> + </param_driver> + </param> - <param - id="773" - group="0" - wearable="shape" - edit_group="shape_head" - edit_group_order="4.5" - name="Head Length" - label_min="Flat Head" - label_max="Long Head" - value_min="0" - value_max="1" - value_default=".5" - camera_elevation=".1" - camera_distance=".5" - camera_angle="75"> - <param_driver> - <driven - id="770" /> + <param + id="802" + group="0" + wearable="shirt" + edit_group="shirt" + edit_group_order="3" + name="Collar Front" + show_simple="true" + label_min="Low" + label_max="High" + value_min="0" + value_max="1" + value_default=".78" + simple_percent_min="40" + simple_percent_max="100" + camera_distance="1.2" + camera_angle="15" + camera_elevation=".2"> + <param_driver> + <driven + id="602" /> + + <driven + id="1015" /> + + <driven + id="1031" /> + + <driven + id="902" + min1="0" + max1=".98" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="771" /> + <param + id="781" + group="0" + wearable="shirt" + edit_group="shirt" + edit_group_order="3.1" + name="Collar Back" + label_min="Low" + label_max="High" + value_min="0" + value_max="1" + value_default=".78" + camera_distance="1.2" + camera_angle="195" + camera_elevation=".2"> + <param_driver> + <driven + id="778" /> + + <driven + id="1016" /> + + <driven + id="1032" /> + + <driven + id="903" + min1="0" + max1=".98" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="772" /> - </param_driver> - </param> + <param + id="150" + group="0" + wearable="skin" + edit_group="skin_bodydetail" + name="Body Definition" + label_min="Less" + label_max="More" + value_min="0" + value_max="1" + value_default="0" + camera_distance="1.4" + camera_elevation="-.2"> + <param_driver> + <driven + id="125" /> + + <driven + id="126" /> + + <driven + id="160" /> + + <driven + id="161" /> + + <driven + id="874" /> + + <driven + id="878" /> + + </param_driver> + </param> - <param - id="682" - group="0" - wearable="shape" - edit_group="shape_head" - edit_group_order="1" - name="Head Size" - label="Head Size" - label_min="Small Head" - label_max="Big Head" - show_simple="true" - value_min="0" - value_max="1" - value_default=".5" - camera_elevation=".1" - camera_distance=".5"> - <param_driver> - <driven - id="679" /> + <param + id="775" + group="0" + wearable="skin" + edit_group="skin_bodydetail" + name="Body Freckles" + label_min="Less Freckles" + label_max="More Freckles" + value_min="0" + value_max="1" + value_default="0" + camera_distance="1.4" + camera_elevation="-.2"> + <param_driver> + <driven + id="776" /> + + <driven + id="777" /> + </param_driver> + </param> - <driven - id="694" /> + <param + id="162" + group="0" + wearable="skin" + edit_group="skin_facedetail" + edit_group_order="1" + name="Facial Definition" + label_min="Less" + label_max="More" + value_min="0" + value_max="1" + camera_distance=".3" + camera_elevation=".07" + value_default="0"> + <param_driver> + <driven + id="158" /> + + <driven + id="159" /> + + <driven + id="873" /> + </param_driver> + </param> - <driven - id="680" /> + <param + id="163" + group="0" + wearable="skin" + edit_group="skin_facedetail" + edit_group_order="3" + name="wrinkles" + label_min="Less" + label_max="More" + value_min="0" + value_max="1" + camera_distance=".3" + camera_elevation=".07" + value_default="0"> + <param_driver> + <!--<driven + id="128" />--> + <driven + id="118" /> + </param_driver> + </param> - <driven - id="681" /> + <param + id="505" + group="0" + wearable="shape" + edit_group="shape_mouth" + edit_group_order="3" + name="Lip Thickness" + label_min="Thin Lips" + label_max="Fat Lips" + value_min="0" + value_max="1" + value_default=".5" + camera_distance=".3" + camera_elevation=".04" + camera_angle="20"> + <param_driver> + <driven + id="26" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="28" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="655" /> - </param_driver> - </param> + <param + id="799" + group="0" + wearable="shape" + edit_group="shape_mouth" + edit_group_order="3.2" + name="Lip Ratio" + label="Lip Ratio" + show_simple="true" + label_min="More Upper Lip" + label_max="More Lower Lip" + value_min="0" + value_max="1" + value_default=".5" + camera_distance=".3" + camera_elevation=".04" + camera_angle="20"> + <param_driver> + <driven + id="797" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="798" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <param - id="690" - group="0" - wearable="shape" - edit_group="shape_eyes" - edit_group_order="1" - name="Eye Size" - label="Eye Size" - label_min="Beady Eyes" - label_max="Anime Eyes" - value_min="0" - value_max="1" - value_default=".5" - show_simple="true" - camera_elevation=".1" - camera_distance=".35"> - <param_driver> - <driven - id="686" /> + <param + id="155" + group="0" + wearable="shape" + edit_group="shape_mouth" + edit_group_order="1" + name="Lip Width" + label="Lip Width" + label_min="Narrow Lips" + label_max="Wide Lips" + show_simple="true" + value_min="-0.9" + value_max="1.3" + camera_distance=".3" + camera_elevation=".04" + value_default="0"> + <param_driver> + <driven + id="29" /> + + <driven + id="30" /> + </param_driver> + </param> - <driven - id="687" /> + <param + id="196" + group="0" + wearable="shape" + edit_group="shape_eyes" + edit_group_order="2" + name="Eye Spacing" + label="Eye Spacing" + label_min="Close Set Eyes" + label_max="Far Set Eyes" + show_simple="true" + value_min="-2" + value_max="1" + value_default="0" + camera_elevation=".1" + camera_distance=".35" + camera_angle="5"> + <param_driver> + <driven + id="194" /> + + <driven + id="195" /> + </param_driver> + </param> - <driven - id="695" /> + <param + id="769" + group="0" + wearable="shape" + edit_group="shape_eyes" + edit_group_order="4.5" + name="Eye Depth" + label_min="Sunken Eyes" + label_max="Bugged Eyes" + value_min="0" + value_max="1" + value_default=".5" + camera_elevation=".1" + camera_distance=".3" + camera_angle="75"> + <param_driver> + <driven + id="767" /> + + <driven + id="768" /> + </param_driver> + </param> - <driven - id="688" /> + <param + id="198" + group="0" + wearable="shoes" + edit_group="shoes" + edit_group_order="2" + name="Heel Height" + label_min="Low Heels" + label_max="High Heels" + value_min="0" + value_max="1" + value_default="0" + camera_angle="45" + camera_distance=".8" + camera_elevation="-1"> + <param_driver> + <driven + id="197" /> + + <driven + id="500" /> + </param_driver> + </param> - <driven - id="691" /> + <param + id="513" + group="0" + wearable="shoes" + edit_group="shoes" + edit_group_order="3" + name="Heel Shape" + label_min="Pointy Heels" + label_max="Thick Heels" + value_min="0" + value_max="1" + value_default=".5" + camera_angle="45" + camera_distance="1.5" + camera_elevation="-1"> + <param_driver> + <driven + id="509" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="510" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="689" /> - </param_driver> - </param> + <param + id="514" + group="0" + wearable="shoes" + edit_group="shoes" + edit_group_order="4" + name="Toe Shape" + label_min="Pointy" + label_max="Square" + value_min="0" + value_max="1" + value_default=".5" + camera_angle="5" + camera_distance=".8" + camera_elevation="-.8"> + <param_driver> + <driven + id="511" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="512" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <param - id="752" - group="0" - sex="male" - wearable="hair" - edit_group="hair_facial" - edit_group_order="1" - name="Hair Thickness" - label_min="5 O'Clock Shadow" - label_max="Bushy Hair" - value_min="0" - value_max="1" - value_default=".5" - camera_elevation="0" - camera_distance=".28"> - <param_driver> - <driven - id="751" - min1="0" - max1="0" - max2="0" - min2=".2" /> - - <driven - id="1012" - min1="0" - max1="0" - max2=".2" - min2=".6" /> - - <driven - id="400" - min1=".2" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> - - <param - id="763" - group="0" - wearable="hair" - edit_group="hair_style" - edit_group_order="1" - name="Hair Volume" - show_simple="true" - label_min="Less Volume" - label_max="More Volume" - value_min="0" - value_max="1" - value_default=".55" - camera_elevation=".1" - camera_distance=".5" - camera_angle="20"> - <param_driver> - <driven - id="761" - min1="0" - max1="0" - max2="0" - min2=".5" /> + <param + id="503" + group="0" + wearable="shoes" + edit_group="shoes" + edit_group_order="6" + name="Platform Height" + label_min="Low Platforms" + label_max="High Platforms" + value_min="0" + value_max="1" + value_default="0" + camera_angle="45" + camera_distance=".5" + camera_elevation="-1"> + <param_driver> + <driven + id="501" /> + + <driven + id="502" /> + </param_driver> + </param> - <driven - id="180" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> + <param + id="193" + group="0" + wearable="shape" + edit_group="shape_head" + edit_group_order="3" + name="Head Shape" + label="Head Shape" + label_min="More Square" + label_max="More Round" + show_simple="true" + value_min="0" + value_max="1" + value_default=".5" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_driver> + <driven + id="188" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="642" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="189" + min1=".5" + max1="1" + max2="1" + min2="1" /> + + <driven + id="643" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <param - id="834" - group="0" - wearable="jacket" - edit_group="colorpicker" - name="jacket_red" - value_min="0" - value_max="1" - value_default="1"> - <param_driver> - <driven - id="809" - min1="0" - max1="1" - max2="1" - min2="1" /> + <param + id="157" + group="0" + wearable="shape" + edit_group="shape_torso" + edit_group_order="13" + name="Belly Size" + label_min="Small" + label_max="Big" + value_min="0" + value_max="1" + value_default="0" + camera_distance="1.4" + camera_angle="30" + camera_elevation=".2"> + <param_driver> + <driven + id="104" /> + + <driven + id="156" /> + + <driven + id="849" /> + </param_driver> + </param> - <driven - id="831" - min1="0" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> + <param + id="637" + group="0" + wearable="shape" + edit_group="shape_body" + edit_group_order="3" + name="Body Fat" + label_min="Less Body Fat" + label_max="More Body Fat" + value_min="0" + value_max="1" + value_default="0" + camera_distance="1.8"> + <param_driver> + <driven + id="633" /> + + <driven + id="634" /> + + <driven + id="635" /> + + <driven + id="851" /> + </param_driver> + </param> - <param - id="835" - group="0" - wearable="jacket" - edit_group="colorpicker" - name="jacket_green" - value_min="0" - value_max="1" - value_default="1"> - <param_driver> - <driven - id="810" - min1="0" - max1="1" - max2="1" - min2="1" /> + <param + id="130" + group="0" + wearable="hair" + edit_group="hair_style" + edit_group_order="8" + name="Front Fringe" + label_min="Short" + label_max="Long" + value_min="0" + value_max="1" + value_default=".45" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_driver> + <driven + id="144" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="145" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="832" - min1="0" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> + <param + id="131" + group="0" + wearable="hair" + edit_group="hair_style" + edit_group_order="9" + name="Side Fringe" + label_min="Short" + label_max="Long" + value_min="0" + value_max="1" + value_default=".5" + camera_elevation=".1" + camera_distance=".5" + camera_angle="90"> + <param_driver> + <driven + id="146" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="147" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <param - id="836" - group="0" - wearable="jacket" - edit_group="colorpicker" - name="jacket_blue" - value_min="0" - value_max="1" - value_default="1"> - <param_driver> - <driven - id="811" - min1="0" - max1="1" - max2="1" - min2="1" /> + <param + id="132" + group="0" + wearable="hair" + edit_group="hair_style" + edit_group_order="10" + name="Back Fringe" + label_min="Short" + label_max="Long" + value_min="0" + value_max="1" + value_default=".39" + camera_elevation=".1" + camera_distance=".5" + camera_angle="160"> + <param_driver> + <driven + id="148" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="149" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="833" - min1="0" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> + <param + id="133" + group="0" + wearable="hair" + edit_group="hair_style" + edit_group_order="2" + name="Hair Front" + label_min="Short" + label_max="Long" + value_min="0" + value_max="1" + value_default=".25" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_driver> + <driven + id="172" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="171" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <param - id="785" - group="0" - wearable="hair" - edit_group="hair_style" - edit_group_order="14.6" - name="Pigtails" - show_simple="true" - label_min="Short Pigtails" - label_max="Long Pigtails" - value_min="0" - value_max="1" - value_default="0" - camera_elevation=".1" - camera_distance=".5" - camera_angle="15"> - <param_driver> - <driven - id="782" - min1="0" - max1=".10" - max2=".10" - min2=".5" /> - - <driven - id="783" - min1=".10" - max1=".5" - max2=".5" - min2=".75" /> - - <driven - id="790" - min1=".5" - max1=".75" - max2=".75" - min2="1" /> - - <driven - id="784" - min1=".75" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> - - <param - id="789" - group="0" - wearable="hair" - edit_group="hair_style" - edit_group_order="14.7" - name="Ponytail" - label_min="Short Ponytail" - label_max="Long Ponytail" - value_min="0" - value_max="1" - value_default="0" - camera_elevation=".1" - camera_distance=".5" - camera_angle="180"> - <param_driver> - <driven - id="786" - min1="0" - max1=".10" - max2=".10" - min2=".66" /> - - <driven - id="787" - min1=".10" - max1=".66" - max2=".66" - min2="1" /> - - <driven - id="788" - min1=".66" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> - - <param - id="795" - group="0" - name="Butt Size" - label="Butt Size" - wearable="shape" - edit_group="shape_legs" - edit_group_order="4" - label_min="Flat Butt" - label_max="Big Butt" - value_min="0" - value_max="1" - value_default=".25" - camera_angle="180" - camera_distance=".6"> - <param_driver> - <driven - id="867" - min1="0" - max1="0" - max2="0" - min2=".3" /> - - <driven - id="794" - min1="0" - max1="0" - max2="0" - min2=".3" /> - - <driven - id="151" - min1=".3" - max1="1" - max2="1" - min2="1" /> - - <driven - id="852" - min1=".3" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> - - <param - id="841" - group="0" - name="Bowed_Legs" - label="Knee Angle" - wearable="shape" - edit_group_order="5.5" - edit_group="shape_legs" - label_min="Knock Kneed" - label_max="Bow Legged" - value_min="-1" - value_max="1" - value_default="0" - camera_distance="1.3" - camera_elevation="-.5"> - <param_driver> - <driven - id="853" /> + <param + id="134" + group="0" + wearable="hair" + edit_group="hair_style" + edit_group_order="3" + name="Hair Sides" + label_min="Short" + label_max="Long" + value_min="0" + value_max="1" + value_default=".5" + camera_elevation=".1" + camera_distance=".5" + camera_angle="90"> + <param_driver> + <driven + id="174" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="173" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="847" /> - </param_driver> - </param> + <param + id="135" + group="0" + wearable="hair" + edit_group="hair_style" + edit_group_order="4" + name="Hair Back" + show_simple="true" + label_min="Short" + label_max="Long" + value_min="0" + value_max="1" + value_default=".55" + camera_elevation="-.1" + camera_distance=".8" + camera_angle="160"> + <param_driver> + <driven + id="176" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="175" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <param - id="753" - group="0" - name="Saddlebags" - label="Saddle Bags" - wearable="shape" - edit_group="shape_legs" - edit_group_order="5" - label_min="Less Saddle" - label_max="More Saddle" - value_min="-0.5" - value_max="3" - value_default="0" - camera_angle="0" - camera_distance="1.2"> - <param_driver> - <driven - id="850" /> + <param + id="136" + group="0" + wearable="hair" + edit_group="hair_style" + edit_group_order="11.5" + name="Hair Sweep" + label_min="Sweep Forward" + label_max="Sweep Back" + value_min="0" + value_max="1" + value_default=".5" + camera_elevation=".1" + camera_distance=".5" + camera_angle="90"> + <param_driver> + <driven + id="179" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="178" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="854" /> - </param_driver> - </param> + <param + id="137" + group="0" + wearable="hair" + edit_group="hair_style" + edit_group_order="16" + name="Hair Tilt" + label_min="Left" + label_max="Right" + value_min="0" + value_max="1" + value_default=".5" + camera_elevation=".1" + camera_distance=".5" + camera_angle="0"> + <param_driver> + <driven + id="190" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="191" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <param - id="676" - group="0" - name="Love_Handles" - label="Love Handles" - wearable="shape" - edit_group="shape_torso" - edit_group_order="12" - label_min="Less Love" - label_max="More Love" - value_min="-1" - value_max="2" - value_default="0" - camera_elevation=".3" - camera_distance=".9"> - <param_driver> - <driven - id="855" /> + <param + id="608" + group="0" + wearable="jacket" + edit_group="jacket" + edit_group_order="2" + name="bottom length lower" + label="Jacket Length" + label_min="Short" + label_max="Long" + value_min="0" + value_max="1" + value_default=".8" + camera_distance="1.4" + camera_angle="30" + camera_elevation=".2"> + <param_driver> + <driven + id="620" /> + + <driven + id="1025" /> + + <driven + id="1037" /> + + <driven + id="621" /> + + <driven + id="1027" /> + + <driven + id="1033" /> + </param_driver> + </param> - <driven - id="856" /> - </param_driver> - </param> + <param + id="609" + group="0" + wearable="jacket" + edit_group="jacket" + edit_group_order="4" + name="open jacket" + label="Open Front" + label_min="Open" + label_max="Closed" + value_min="0" + value_max="1" + value_default=".2" + camera_distance="1.4" + camera_angle="30" + camera_elevation=".2"> + <param_driver> + <driven + id="622" /> + + <driven + id="1026" /> + + <driven + id="1038" /> + + <driven + id="623" /> + + <driven + id="1028" /> + + <driven + id="1034" /> + </param_driver> + </param> - <param - id="863" - group="0" - name="skirt_looseness" - label="Skirt Fit" - show_simple="true" - clothing_morph="true" - wearable="skirt" - edit_group_order="2" - edit_group="skirt" - label_min="Tight Skirt" - label_max="Poofy Skirt" - value_min="0" - value_max="1" - value_default=".333" - camera_distance="1.3" - camera_elevation="-.5"> - <param_driver> - <driven - id="866" - min1="0" - max1="0" - max2="0" - min2=".2" /> - - <driven - id="846" - min1="0" - max1=".5" - max2=".5" - min2="1" /> - - <driven - id="845" - min1=".5" - max1="1" - max2="1" - min2="1" /> - </param_driver> - </param> - - <param - id="119" - group="0" - wearable="hair" - edit_group="hair_eyebrows" - edit_group_order="1" - name="Eyebrow Size" - show_simple="true" - label_min="Thin Eyebrows" - label_max="Bushy Eyebrows" - value_min="0" - value_max="1" - value_default="0.5" - camera_elevation=".1" - camera_distance=".3"> - <param_driver> - <driven - id="1000" /> + <param + id="105" + group="0" + sex="female" + wearable="shape" + edit_group="shape_torso" + edit_group_order="6" + name="Breast Size" + label_min="Small" + label_max="Large" + value_min="0" + value_max="1" + value_default=".5" + camera_elevation=".3" + camera_distance="1.2" + camera_angle="30"> + <param_driver> + <driven + id="843" + min1="0" + max1="0" + max2="0" + min2=".01" /> + + <driven + id="627" + min1="0" + max1="0.01" + max2="0.01" + min2=".5" /> + + <driven + id="626" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="1001" /> - </param_driver> - </param> + <param + id="629" + group="0" + wearable="shape" + edit_group="shape_head" + edit_group_order="6" + name="Forehead Angle" + label_min="More Vertical" + label_max="More Sloped" + value_min="0" + value_max="1" + value_default=".5" + camera_elevation=".1" + camera_distance=".5" + camera_angle="70"> + <param_driver> + <driven + id="630" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="644" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="631" + min1=".5" + max1="1" + max2="1" + min2="1" /> + + <driven + id="645" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <param - id="750" - group="0" - wearable="hair" - edit_group="hair_eyebrows" - edit_group_order="2" - name="Eyebrow Density" - label_min="Sparse" - label_max="Dense" - value_min="0" - value_max="1" - value_default="0.7" - camera_elevation=".1" - camera_distance=".3"> - <param_driver> - <driven - id="1002" /> + <param + id="646" + group="0" + name="Egg_Head" + label="Egg Head" + wearable="shape" + edit_group="shape_head" + edit_group_order="4" + label_min="Chin Heavy" + label_max="Forehead Heavy" + show_simple="true" + value_min="-1.3" + value_max="1" + value_default="0" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_driver> + <driven + id="640" /> + + <driven + id="186" /> + </param_driver> + </param> - <driven - id="1003" /> - </param_driver> - </param> + <param + id="647" + group="0" + name="Squash_Stretch_Head" + label="Head Stretch" + wearable="shape" + edit_group="shape_head" + edit_group_order="2" + show_simple="true" + label_min="Squash Head" + label_max="Stretch Head" + value_min="-0.5" + value_max="1" + value_default="0" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_driver> + <driven + id="641" /> + + <driven + id="187" /> + </param_driver> + </param> - <param - id="166" - sex="male" - group="0" - wearable="hair" - edit_group="hair_facial" - edit_group_order="2" - name="Sideburns" - show_simple="true" - label_min="Short Sideburns" - label_max="Mutton Chops" - value_min="0" - value_max="1" - value_default="0.0" - camera_elevation=".1" - camera_distance=".3" - camera_angle="30"> - <param_driver> - <driven - id="1004" /> + <param + id="649" + group="0" + sex="female" + wearable="shape" + edit_group="shape_torso" + edit_group_order="1.1" + name="Torso Muscles" + label="Torso Muscles" + show_simple="true" + label_min="Less Muscular" + label_max="More Muscular" + value_min="0" + value_max="1" + value_default=".5" + camera_elevation=".1" + camera_distance="1" + camera_angle="15"> + <param_driver> + <driven + id="648" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="106" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="1005" /> - </param_driver> - </param> + <param + id="678" + group="0" + sex="male" + wearable="shape" + edit_group="shape_torso" + edit_group_order="1" + name="Torso Muscles" + show_simple="true" + label_min="Less Muscular" + label_max="More Muscular" + value_min="0" + value_max="1" + value_default=".5" + camera_elevation=".1" + camera_distance="1.2" + camera_angle="0"> + <param_driver> + <driven + id="677" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="106" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <param - id="167" - sex="male" - group="0" - wearable="hair" - edit_group="hair_facial" - edit_group_order="3" - name="Moustache" - show_simple="true" - label_min="Chaplin" - label_max="Handlebars" - value_min="0" - value_max="1" - value_default="0.0" - camera_elevation=".1" - camera_distance=".3" - camera_angle="30"> - <param_driver> - <driven - id="1006" /> + <param + id="652" + group="0" + wearable="shape" + edit_group="shape_legs" + edit_group_order="1" + name="Leg Muscles" + label_min="Less Muscular" + label_max="More Muscular" + show_simple="true" + value_min="0" + value_max="1" + value_default=".5" + camera_distance="1.3" + camera_elevation="-.5" + camera_angle="15"> + <param_driver> + <driven + id="651" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="152" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="1007" /> - </param_driver> - </param> + <param + id="80" + name="male" + group="0" + edit_group="dummy" + wearable="shape" + value_min="0" + value_max="1"> + <param_driver> + <driven + id="32" /> + + <driven + id="153" /> + + <driven + id="40" /> + + <driven + id="100" /> + + <driven + id="857" /> + </param_driver> + </param> - <param - id="168" - sex="male" - group="0" - wearable="hair" - edit_group="hair_facial" - edit_group_order="5" - name="Soulpatch" - show_simple="true" - label_min="Less soul" - label_max="More soul" - value_min="0" - value_max="1" - value_default="0.0" - camera_elevation="-.1" - camera_distance=".3" - camera_angle="0"> - <param_driver> - <driven - id="1008" /> + <param + id="659" + group="0" + wearable="shape" + edit_group="shape_mouth" + edit_group_order="5" + name="Mouth Corner" + label_min="Corner Down" + label_max="Corner Up" + value_min="0" + value_max="1" + value_default=".5" + camera_elevation="0" + camera_distance=".28"> + <param_driver> + <driven + id="658" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="657" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="1009" /> - </param_driver> - </param> + <param + id="662" + group="0" + wearable="shape" + edit_group="shape_head" + edit_group_order="5" + name="Face Shear" + label_min="Shear Right Up" + label_max="Shear Left Up" + value_min="0" + value_max="1" + value_default=".5" + camera_elevation=".1" + camera_distance=".5"> + <param_driver> + <driven + id="660" /> + + <driven + id="661" /> + + <driven + id="774" /> + </param_driver> + </param> - <param - id="169" - sex="male" - group="0" - wearable="hair" - edit_group="hair_facial" - edit_group_order="4" - name="Chin Curtains" - show_simple="true" - label_min="Less Curtains" - label_max="More Curtains" - value_min="0" - value_max="1" - value_default="0.0" - camera_elevation="-.1" - camera_distance=".3" - camera_angle="45"> - <param_driver> - <driven - id="1010" /> + <param + id="773" + group="0" + wearable="shape" + edit_group="shape_head" + edit_group_order="4.5" + name="Head Length" + label_min="Flat Head" + label_max="Long Head" + value_min="0" + value_max="1" + value_default=".5" + camera_elevation=".1" + camera_distance=".5" + camera_angle="75"> + <param_driver> + <driven + id="770" /> + + <driven + id="771" /> + + <driven + id="772" /> + </param_driver> + </param> - <driven - id="1011" /> - </param_driver> - </param> + <param + id="682" + group="0" + wearable="shape" + edit_group="shape_head" + edit_group_order="1" + name="Head Size" + label="Head Size" + label_min="Small Head" + label_max="Big Head" + show_simple="true" + value_min="0" + value_max="1" + value_default=".5" + camera_elevation=".1" + camera_distance=".5"> + <param_driver> + <driven + id="679" /> + + <driven + id="694" /> + + <driven + id="680" /> + + <driven + id="681" /> + + <driven + id="655" /> + </param_driver> + </param> - <param - id="606" - group="0" - wearable="jacket" - edit_group="jacket" - edit_group_order="1" - name="Sleeve Length" - label_min="Short" - label_max="Long" - value_min="0" - value_max="1" - value_default=".8" - camera_distance="1.2" - camera_angle="30" - camera_elevation=".2"> - <param_driver> - <driven - id="1019" /> + <param + id="690" + group="0" + wearable="shape" + edit_group="shape_eyes" + edit_group_order="1" + name="Eye Size" + label="Eye Size" + label_min="Beady Eyes" + label_max="Anime Eyes" + value_min="0" + value_max="1" + value_default=".5" + show_simple="true" + camera_elevation=".1" + camera_distance=".35"> + <param_driver> + <driven + id="686" /> + + <driven + id="687" /> + + <driven + id="695" /> + + <driven + id="688" /> + + <driven + id="691" /> + + <driven + id="689" /> + </param_driver> + </param> - <driven - id="1039" /> + <param + id="752" + group="0" + sex="male" + wearable="hair" + edit_group="hair_facial" + edit_group_order="1" + name="Hair Thickness" + label_min="5 O'Clock Shadow" + label_max="Bushy Hair" + value_min="0" + value_max="1" + value_default=".5" + camera_elevation="0" + camera_distance=".28"> + <param_driver> + <driven + id="751" + min1="0" + max1="0" + max2="0" + min2=".2" /> + + <driven + id="1012" + min1="0" + max1="0" + max2=".2" + min2=".6" /> + + <driven + id="400" + min1=".2" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="1020" /> - </param_driver> - </param> + <param + id="763" + group="0" + wearable="hair" + edit_group="hair_style" + edit_group_order="1" + name="Hair Volume" + show_simple="true" + label_min="Less Volume" + label_max="More Volume" + value_min="0" + value_max="1" + value_default=".55" + camera_elevation=".1" + camera_distance=".5" + camera_angle="20"> + <param_driver> + <driven + id="761" + min1="0" + max1="0" + max2="0" + min2=".5" /> + + <driven + id="180" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <param - id="607" - group="0" - wearable="jacket" - edit_group="jacket" - edit_group_order="3" - name="Collar Front" - label_min="Low" - label_max="High" - value_min="0" - value_max="1" - value_default=".8" - camera_distance="1.2" - camera_angle="15" - camera_elevation=".2"> - <param_driver> - <driven - id="1021" /> + <param + id="834" + group="0" + wearable="jacket" + edit_group="colorpicker" + name="jacket_red" + value_min="0" + value_max="1" + value_default="1"> + <param_driver> + <driven + id="809" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="831" + min1="0" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="1040" /> + <param + id="835" + group="0" + wearable="jacket" + edit_group="colorpicker" + name="jacket_green" + value_min="0" + value_max="1" + value_default="1"> + <param_driver> + <driven + id="810" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="832" + min1="0" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="1022" /> - </param_driver> - </param> + <param + id="836" + group="0" + wearable="jacket" + edit_group="colorpicker" + name="jacket_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_driver> + <driven + id="811" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="833" + min1="0" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <param - id="780" - group="0" - wearable="jacket" - edit_group="jacket" - edit_group_order="3.5" - name="Collar Back" - label_min="Low" - label_max="High" - value_min="0" - value_max="1" - value_default=".8" - camera_distance="1.2" - camera_angle="195" - camera_elevation=".2"> - <param_driver> - <driven - id="1023" /> + <param + id="785" + group="0" + wearable="hair" + edit_group="hair_style" + edit_group_order="14.6" + name="Pigtails" + show_simple="true" + label_min="Short Pigtails" + label_max="Long Pigtails" + value_min="0" + value_max="1" + value_default="0" + camera_elevation=".1" + camera_distance=".5" + camera_angle="15"> + <param_driver> + <driven + id="782" + min1="0" + max1=".10" + max2=".10" + min2=".5" /> + + <driven + id="783" + min1=".10" + max1=".5" + max2=".5" + min2=".75" /> + + <driven + id="790" + min1=".5" + max1=".75" + max2=".75" + min2="1" /> + + <driven + id="784" + min1=".75" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="1041" /> + <param + id="789" + group="0" + wearable="hair" + edit_group="hair_style" + edit_group_order="14.7" + name="Ponytail" + label_min="Short Ponytail" + label_max="Long Ponytail" + value_min="0" + value_max="1" + value_default="0" + camera_elevation=".1" + camera_distance=".5" + camera_angle="180"> + <param_driver> + <driven + id="786" + min1="0" + max1=".10" + max2=".10" + min2=".66" /> + + <driven + id="787" + min1=".10" + max1=".66" + max2=".66" + min2="1" /> + + <driven + id="788" + min1=".66" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <driven - id="1024" /> - </param_driver> - </param> + <param + id="795" + group="0" + name="Butt Size" + label="Butt Size" + wearable="shape" + edit_group="shape_legs" + edit_group_order="4" + label_min="Flat Butt" + label_max="Big Butt" + value_min="0" + value_max="1" + value_default=".25" + camera_angle="180" + camera_distance=".6"> + <param_driver> + <driven + id="867" + min1="0" + max1="0" + max2="0" + min2=".3" /> + + <driven + id="794" + min1="0" + max1="0" + max2="0" + min2=".3" /> + + <driven + id="151" + min1=".3" + max1="1" + max2="1" + min2="1" /> + + <driven + id="852" + min1=".3" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <param - id="603" - group="0" - wearable="undershirt" - edit_group="undershirt" - edit_group_order="1" - name="Sleeve Length" - label_min="Short" - label_max="Long" - value_min=".01" - value_max="1" - value_default=".4" - camera_distance="1.2" - camera_angle="30" - camera_elevation=".2"> - <param_driver> - <driven - id="1042" /> + <param + id="841" + group="0" + name="Bowed_Legs" + label="Knee Angle" + wearable="shape" + edit_group_order="5.5" + edit_group="shape_legs" + label_min="Knock Kneed" + label_max="Bow Legged" + value_min="-1" + value_max="1" + value_default="0" + camera_distance="1.3" + camera_elevation="-.5"> + <param_driver> + <driven + id="853" /> + + <driven + id="847" /> + </param_driver> + </param> - <driven - id="1043" /> - </param_driver> - </param> + <param + id="753" + group="0" + name="Saddlebags" + label="Saddle Bags" + wearable="shape" + edit_group="shape_legs" + edit_group_order="5" + label_min="Less Saddle" + label_max="More Saddle" + value_min="-0.5" + value_max="3" + value_default="0" + camera_angle="0" + camera_distance="1.2"> + <param_driver> + <driven + id="850" /> + + <driven + id="854" /> + </param_driver> + </param> - <param - id="604" - group="0" - wearable="undershirt" - edit_group="undershirt" - edit_group_order="2" - name="Bottom" - label_min="Short" - label_max="Long" - value_min="0" - value_max="1" - value_default=".85" - camera_distance="1.2" - camera_angle="30" - camera_elevation=".2"> - <param_driver> - <driven - id="1044" /> + <param + id="676" + group="0" + name="Love_Handles" + label="Love Handles" + wearable="shape" + edit_group="shape_torso" + edit_group_order="12" + label_min="Less Love" + label_max="More Love" + value_min="-1" + value_max="2" + value_default="0" + camera_elevation=".3" + camera_distance=".9"> + <param_driver> + <driven + id="855" /> + + <driven + id="856" /> + </param_driver> + </param> - <driven - id="1045" /> - </param_driver> - </param> + <param + id="863" + group="0" + name="skirt_looseness" + label="Skirt Fit" + show_simple="true" + clothing_morph="true" + wearable="skirt" + edit_group_order="2" + edit_group="skirt" + label_min="Tight Skirt" + label_max="Poofy Skirt" + value_min="0" + value_max="1" + value_default=".333" + camera_distance="1.3" + camera_elevation="-.5"> + <param_driver> + <driven + id="866" + min1="0" + max1="0" + max2="0" + min2=".2" /> + + <driven + id="846" + min1="0" + max1=".5" + max2=".5" + min2="1" /> + + <driven + id="845" + min1=".5" + max1="1" + max2="1" + min2="1" /> + </param_driver> + </param> - <param - id="605" - group="0" - wearable="undershirt" - edit_group="undershirt" - edit_group_order="3" - name="Collar Front" - label_min="Low" - label_max="High" - value_min="0" - value_max="1" - value_default=".84" - camera_distance=".8" - camera_angle="15" - camera_elevation=".2"> - <param_driver> - <driven - id="1046" /> + <param + id="119" + group="0" + wearable="hair" + edit_group="hair_eyebrows" + edit_group_order="1" + name="Eyebrow Size" + show_simple="true" + label_min="Thin Eyebrows" + label_max="Bushy Eyebrows" + value_min="0" + value_max="1" + value_default="0.5" + camera_elevation=".1" + camera_distance=".3"> + <param_driver> + <driven + id="1000" /> + + <driven + id="1001" /> + </param_driver> + </param> - <driven - id="1047" /> - </param_driver> - </param> + <param + id="750" + group="0" + wearable="hair" + edit_group="hair_eyebrows" + edit_group_order="2" + name="Eyebrow Density" + label_min="Sparse" + label_max="Dense" + value_min="0" + value_max="1" + value_default="0.7" + camera_elevation=".1" + camera_distance=".3"> + <param_driver> + <driven + id="1002" /> + + <driven + id="1003" /> + </param_driver> + </param> - <param - id="779" - group="0" - wearable="undershirt" - edit_group="undershirt" - edit_group_order="4" - name="Collar Back" - label_min="Low" - label_max="High" - value_min="0" - value_max="1" - value_default=".84" - camera_distance=".8" - camera_angle="195" - camera_elevation=".2"> - <param_driver> - <driven - id="1048" /> + <param + id="166" + sex="male" + group="0" + wearable="hair" + edit_group="hair_facial" + edit_group_order="2" + name="Sideburns" + show_simple="true" + label_min="Short Sideburns" + label_max="Mutton Chops" + value_min="0" + value_max="1" + value_default="0.0" + camera_elevation=".1" + camera_distance=".3" + camera_angle="30"> + <param_driver> + <driven + id="1004" /> + + <driven + id="1005" /> + </param_driver> + </param> - <driven - id="1049" /> - </param_driver> - </param> + <param + id="167" + sex="male" + group="0" + wearable="hair" + edit_group="hair_facial" + edit_group_order="3" + name="Moustache" + show_simple="true" + label_min="Chaplin" + label_max="Handlebars" + value_min="0" + value_max="1" + value_default="0.0" + camera_elevation=".1" + camera_distance=".3" + camera_angle="30"> + <param_driver> + <driven + id="1006" /> + + <driven + id="1007" /> + </param_driver> + </param> - <param - id="617" - group="0" - wearable="socks" - edit_group="socks" - name="Socks Length" - label_min="Short" - label_max="Long" - value_min="0" - value_max="1" - value_default="0.35" - camera_distance=".95" - camera_angle="30" - camera_elevation="-.75"> - <param_driver> - <driven - id="1050" /> + <param + id="168" + sex="male" + group="0" + wearable="hair" + edit_group="hair_facial" + edit_group_order="5" + name="Soulpatch" + show_simple="true" + label_min="Less soul" + label_max="More soul" + value_min="0" + value_max="1" + value_default="0.0" + camera_elevation="-.1" + camera_distance=".3" + camera_angle="0"> + <param_driver> + <driven + id="1008" /> + + <driven + id="1009" /> + </param_driver> + </param> - <driven - id="1051" /> - </param_driver> - </param> + <param + id="169" + sex="male" + group="0" + wearable="hair" + edit_group="hair_facial" + edit_group_order="4" + name="Chin Curtains" + show_simple="true" + label_min="Less Curtains" + label_max="More Curtains" + value_min="0" + value_max="1" + value_default="0.0" + camera_elevation="-.1" + camera_distance=".3" + camera_angle="45"> + <param_driver> + <driven + id="1010" /> + + <driven + id="1011" /> + </param_driver> + </param> - <param - id="616" - group="0" - wearable="shoes" - edit_group="shoes" - edit_group_order="1" - name="Shoe Height" - label_min="Short" - label_max="Tall" - value_min="0" - value_max="1" - value_default="0.1" - camera_distance="1.2" - camera_angle="30" - camera_elevation="-.75"> - <param_driver> - <driven - id="1052" /> + <param + id="606" + group="0" + wearable="jacket" + edit_group="jacket" + edit_group_order="1" + name="Sleeve Length" + label_min="Short" + label_max="Long" + value_min="0" + value_max="1" + value_default=".8" + camera_distance="1.2" + camera_angle="30" + camera_elevation=".2"> + <param_driver> + <driven + id="1019" /> + + <driven + id="1039" /> + + <driven + id="1020" /> + </param_driver> + </param> - <driven - id="1053" /> - </param_driver> - </param> + <param + id="607" + group="0" + wearable="jacket" + edit_group="jacket" + edit_group_order="3" + name="Collar Front" + label_min="Low" + label_max="High" + value_min="0" + value_max="1" + value_default=".8" + camera_distance="1.2" + camera_angle="15" + camera_elevation=".2"> + <param_driver> + <driven + id="1021" /> + + <driven + id="1040" /> + + <driven + id="1022" /> + </param_driver> + </param> - <param - id="619" - group="0" - wearable="underpants" - edit_group="underpants" - name="Pants Length" - label_min="Short" - label_max="Long" - value_min="0" - value_max="1" - value_default=".3" - camera_distance="1.2" - camera_angle="30" - camera_elevation="-.3"> - <param_driver> - <driven - id="1054" /> + <param + id="780" + group="0" + wearable="jacket" + edit_group="jacket" + edit_group_order="3.5" + name="Collar Back" + label_min="Low" + label_max="High" + value_min="0" + value_max="1" + value_default=".8" + camera_distance="1.2" + camera_angle="195" + camera_elevation=".2"> + <param_driver> + <driven + id="1023" /> + + <driven + id="1041" /> + + <driven + id="1024" /> + </param_driver> + </param> - <driven - id="1055" /> - </param_driver> - </param> + <param + id="603" + group="0" + wearable="undershirt" + edit_group="undershirt" + edit_group_order="1" + name="Sleeve Length" + label_min="Short" + label_max="Long" + value_min=".01" + value_max="1" + value_default=".4" + camera_distance="1.2" + camera_angle="30" + camera_elevation=".2"> + <param_driver> + <driven + id="1042" /> + + <driven + id="1043" /> + </param_driver> + </param> - <param - id="624" - group="0" - wearable="underpants" - edit_group="underpants" - name="Pants Waist" - label_min="Low" - label_max="High" - value_min="0" - value_max="1" - value_default=".8" - camera_distance="1.2" - camera_angle="30" - camera_elevation="-.3"> - <param_driver> - <driven - id="1056" /> + <param + id="604" + group="0" + wearable="undershirt" + edit_group="undershirt" + edit_group_order="2" + name="Bottom" + label_min="Short" + label_max="Long" + value_min="0" + value_max="1" + value_default=".85" + camera_distance="1.2" + camera_angle="30" + camera_elevation=".2"> + <param_driver> + <driven + id="1044" /> + + <driven + id="1045" /> + </param_driver> + </param> - <driven - id="1057" /> - </param_driver> - </param> + <param + id="605" + group="0" + wearable="undershirt" + edit_group="undershirt" + edit_group_order="3" + name="Collar Front" + label_min="Low" + label_max="High" + value_min="0" + value_max="1" + value_default=".84" + camera_distance=".8" + camera_angle="15" + camera_elevation=".2"> + <param_driver> + <driven + id="1046" /> + + <driven + id="1047" /> + </param_driver> + </param> - <param - id="93" - group="0" - wearable="gloves" - edit_group="gloves" - name="Glove Length" - label_min="Short" - label_max="Long" - value_min=".01" - value_max="1" - value_default=".8" - camera_distance="1.2" - camera_angle="30" - camera_elevation=".2"> - <param_driver> - <driven - id="1058" /> + <param + id="779" + group="0" + wearable="undershirt" + edit_group="undershirt" + edit_group_order="4" + name="Collar Back" + label_min="Low" + label_max="High" + value_min="0" + value_max="1" + value_default=".84" + camera_distance=".8" + camera_angle="195" + camera_elevation=".2"> + <param_driver> + <driven + id="1048" /> + + <driven + id="1049" /> + </param_driver> + </param> - <driven - id="1059" /> - </param_driver> - </param> + <param + id="617" + group="0" + wearable="socks" + edit_group="socks" + name="Socks Length" + label_min="Short" + label_max="Long" + value_min="0" + value_max="1" + value_default="0.35" + camera_distance=".95" + camera_angle="30" + camera_elevation="-.75"> + <param_driver> + <driven + id="1050" /> + + <driven + id="1051" /> + </param_driver> + </param> - <param - id="844" - group="0" - wearable="gloves" - edit_group="gloves" - name="Glove Fingers" - label_min="Fingerless" - label_max="Fingers" - value_min=".01" - value_max="1" - value_default="1" - camera_distance="1.2" - camera_angle="30" - camera_elevation=".2"> - <param_driver> - <driven - id="1060" /> + <param + id="616" + group="0" + wearable="shoes" + edit_group="shoes" + edit_group_order="1" + name="Shoe Height" + label_min="Short" + label_max="Tall" + value_min="0" + value_max="1" + value_default="0.1" + camera_distance="1.2" + camera_angle="30" + camera_elevation="-.75"> + <param_driver> + <driven + id="1052" /> + + <driven + id="1053" /> + </param_driver> + </param> - <driven - id="1061" /> - </param_driver> - </param> + <param + id="619" + group="0" + wearable="underpants" + edit_group="underpants" + name="Pants Length" + label_min="Short" + label_max="Long" + value_min="0" + value_max="1" + value_default=".3" + camera_distance="1.2" + camera_angle="30" + camera_elevation="-.3"> + <param_driver> + <driven + id="1054" /> + + <driven + id="1055" /> + </param_driver> + </param> -<!--Pointy eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1--> - <param - id="16" - group="0" - name="Pointy_Eyebrows" - label="Eyebrow Points" - wearable="hair" - edit_group="hair_eyebrows" - edit_group_order="4" - label_min="Smooth" - label_max="Pointy" - value_min="-.5" - value_max="3" - camera_elevation=".1" - camera_distance=".3"> - <param_driver> - <driven - id="870" /> - </param_driver> - </param> + <param + id="624" + group="0" + wearable="underpants" + edit_group="underpants" + name="Pants Waist" + label_min="Low" + label_max="High" + value_min="0" + value_max="1" + value_default=".8" + camera_distance="1.2" + camera_angle="30" + camera_elevation="-.3"> + <param_driver> + <driven + id="1056" /> + + <driven + id="1057" /> + </param_driver> + </param> -<!--Lower eyebrows became a driver/driven param with new min value for backwards compatibility between 1.0 and 1.1--> - <param - id="757" - group="0" - name="Lower_Eyebrows" - label="Eyebrow Height" - show_simple="true" - wearable="hair" - edit_group="hair_eyebrows" - edit_group_order="2.5" - label_min="Higher" - label_max="Lower" - value_min="-4" - value_max="2" - value_default="-1" - camera_elevation=".1" - camera_distance=".3"> - <param_driver> - <driven - id="871" /> - </param_driver> - </param> + <param + id="93" + group="0" + wearable="gloves" + edit_group="gloves" + name="Glove Length" + label_min="Short" + label_max="Long" + value_min=".01" + value_max="1" + value_default=".8" + camera_distance="1.2" + camera_angle="30" + camera_elevation=".2"> + <param_driver> + <driven + id="1058" /> + + <driven + id="1059" /> + </param_driver> + </param> -<!--Arced eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1--> - <param - id="31" - group="0" - name="Arced_Eyebrows" - label="Eyebrow Arc" - wearable="hair" - edit_group="hair_eyebrows" - edit_group_order="3" - label_min="Flat" - label_max="Arced" - value_min="0" - value_max="2" - value_default=".5" - camera_elevation=".1" - camera_distance=".3"> - <param_driver> - <driven - id="872" /> - </param_driver> - </param> + <param + id="844" + group="0" + wearable="gloves" + edit_group="gloves" + name="Glove Fingers" + label_min="Fingerless" + label_max="Fingers" + value_min=".01" + value_max="1" + value_default="1" + camera_distance="1.2" + camera_angle="30" + camera_elevation=".2"> + <param_driver> + <driven + id="1060" /> + + <driven + id="1061" /> + </param_driver> + </param> + + <!--Pointy eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1--> + <param + id="16" + group="0" + name="Pointy_Eyebrows" + label="Eyebrow Points" + wearable="hair" + edit_group="hair_eyebrows" + edit_group_order="4" + label_min="Smooth" + label_max="Pointy" + value_min="-.5" + value_max="3" + camera_elevation=".1" + camera_distance=".3"> + <param_driver> + <driven + id="870" /> + </param_driver> + </param> + + <!--Lower eyebrows became a driver/driven param with new min value for backwards compatibility between 1.0 and 1.1--> + <param + id="757" + group="0" + name="Lower_Eyebrows" + label="Eyebrow Height" + show_simple="true" + wearable="hair" + edit_group="hair_eyebrows" + edit_group_order="2.5" + label_min="Higher" + label_max="Lower" + value_min="-4" + value_max="2" + value_default="-1" + camera_elevation=".1" + camera_distance=".3"> + <param_driver> + <driven + id="871" /> + </param_driver> + </param> + + <!--Arced eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1--> + <param + id="31" + group="0" + name="Arced_Eyebrows" + label="Eyebrow Arc" + wearable="hair" + edit_group="hair_eyebrows" + edit_group_order="3" + label_min="Flat" + label_max="Arced" + value_min="0" + value_max="2" + value_default=".5" + camera_elevation=".1" + camera_distance=".3"> + <param_driver> + <driven + id="872" /> + </param_driver> + </param> - <param - id="877" - group="0" - name="Jacket Wrinkles" - label="Jacket Wrinkles" - wearable="jacket" - edit_group="jacket" - edit_group_order="20" - label_min="No Wrinkles" - label_max="Wrinkles" - value_min="0" - value_max="1" - value_default="0" - camera_elevation=".1" - camera_distance=".3"> - <param_driver> - <driven - id="875" /> + + <param + id="877" + group="0" + name="Jacket Wrinkles" + label="Jacket Wrinkles" + wearable="jacket" + edit_group="jacket" + edit_group_order="20" + label_min="No Wrinkles" + label_max="Wrinkles" + value_min="0" + value_max="1" + value_default="0" + camera_elevation=".1" + camera_distance=".3"> + <param_driver> + <driven + id="875" /> - <driven - id="876" /> - </param_driver> - </param> + + <driven + id="876" /> + </param_driver> + </param> - </driver_parameters> + + </driver_parameters> <morph_masks> <mask diff --git a/indra/newview/installers/windows/lang_it.nsi b/indra/newview/installers/windows/lang_it.nsi Binary files differindex 1208ec4eb8..eccd965a92 100644 --- a/indra/newview/installers/windows/lang_it.nsi +++ b/indra/newview/installers/windows/lang_it.nsi diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index d27bce99a6..f62606cc50 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -45,7 +45,6 @@ #include "llfloateractivespeakers.h" #include "llfloatercamera.h" #include "llfloatercustomize.h" -#include "llfloaterdirectory.h" #include "llfloaterland.h" #include "llfloatersnapshot.h" @@ -3382,13 +3381,18 @@ void LLAgent::updateCamera() { LLVOAvatar::attachment_map_t::iterator curiter = iter++; LLViewerJointAttachment* attachment = curiter->second; - LLViewerObject *attached_object = attachment->getObject(); - if (attached_object && !attached_object->isDead() && attached_object->mDrawable.notNull()) + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) { - // clear any existing "early" movements of attachment - attached_object->mDrawable->clearState(LLDrawable::EARLY_MOVE); - gPipeline.updateMoveNormalAsync(attached_object->mDrawable); - attached_object->updateText(); + LLViewerObject *attached_object = (*attachment_iter); + if (attached_object && !attached_object->isDead() && attached_object->mDrawable.notNull()) + { + // clear any existing "early" movements of attachment + attached_object->mDrawable->clearState(LLDrawable::EARLY_MOVE); + gPipeline.updateMoveNormalAsync(attached_object->mDrawable); + attached_object->updateText(); + } } } @@ -5432,8 +5436,6 @@ void LLAgent::processAgentDropGroup(LLMessageSystem *msg, void **) LLGroupMgr::getInstance()->clearGroupData(group_id); // close the floater for this group, if any. LLGroupActions::closeGroup(group_id); - // refresh the group panel of the search window, if necessary. - LLFloaterDirectory::refreshGroup(group_id); } else { @@ -5511,9 +5513,6 @@ class LLAgentDropGroupViewerNode : public LLHTTPNode LLGroupMgr::getInstance()->clearGroupData(group_id); // close the floater for this group, if any. LLGroupActions::closeGroup(group_id); - // refresh the group panel of the search window, - //if necessary. - LLFloaterDirectory::refreshGroup(group_id); } else { @@ -6324,8 +6323,8 @@ void LLAgent::sendAgentSetAppearance() continue; } - // IMG_DEFAULT_AVATAR means not baked - if (!mAvatarObject->isTextureDefined(texture_index)) + // IMG_DEFAULT_AVATAR means not baked. 0 index should be ignored for baked textures + if (!mAvatarObject->isTextureDefined(texture_index, 0)) { textures_current = FALSE; break; diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 2cfa8d2a54..34d2c00007 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -46,6 +46,7 @@ #include "llwearablelist.h" #include "llgesturemgr.h" #include "llappearancemgr.h" +#include "lltexlayer.h" #include <boost/scoped_ptr.hpp> @@ -65,11 +66,10 @@ public: 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) { } + InitialWearableData(EWearableType type, LLUUID itemID, LLUUID assetID) : + mType(type), mItemID(itemID), mAssetID(assetID) { } }; typedef std::vector<InitialWearableData> initial_wearable_data_vec_t; @@ -139,11 +139,6 @@ 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() @@ -237,10 +232,16 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const S32 type, { wearable->setItemID(item_id); } - setWearable((EWearableType)type,index,wearable); if (old_item_id.notNull()) + { gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id); + setWearable((EWearableType)type,index,wearable); + } + else + { + pushWearable((EWearableType)type,wearable); + } gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); LLViewerInventoryItem* item = gInventory.getItem(item_id); if (item && wearable) @@ -260,11 +261,11 @@ 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 (S32 type=0; type < WT_COUNT; ++type) { - for (U32 j=0; j < getWearableCount((EWearableType)i); j++) + for (U32 j=0; j < getWearableCount((EWearableType)type); ++j) { - LLWearable* wearable = getWearable((EWearableType)i,j); + LLWearable* wearable = getWearable((EWearableType)type,j); if (wearable) { if (wearable->getItemID().isNull()) @@ -272,7 +273,7 @@ void LLAgentWearables::sendAgentWearablesUpdate() LLPointer<LLInventoryCallback> cb = new addWearableToAgentInventoryCallback( LLPointer<LLRefCount>(NULL), - i, + type, j, wearable, addWearableToAgentInventoryCallback::CALL_NONE); @@ -299,15 +300,15 @@ void LLAgentWearables::sendAgentWearablesUpdate() lldebugs << "sendAgentWearablesUpdate()" << llendl; // MULTI-WEARABLE: update for multi-wearables after server-side support is in. - for (S32 i=0; i < WT_COUNT; ++i) + for (S32 type=0; type < WT_COUNT; ++type) { gMessageSystem->nextBlockFast(_PREHASH_WearableData); - U8 type_u8 = (U8)i; + U8 type_u8 = (U8)type; 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); + LLWearable* wearable = getWearable((EWearableType)type, 0); if (wearable) { //llinfos << "Sending wearable " << wearable->getName() << llendl; @@ -327,19 +328,18 @@ void LLAgentWearables::sendAgentWearablesUpdate() gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID::null); } - lldebugs << " " << LLWearableDictionary::getTypeLabel((EWearableType)i) << ": " << (wearable ? wearable->getAssetID() : LLUUID::null) << llendl; + lldebugs << " " << LLWearableDictionary::getTypeLabel((EWearableType)type) << ": " << (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); + LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable); new_wearable->setItemID(old_item_id); // should this be in LLWearable::copyDataFrom()? setWearable(type,index,new_wearable); @@ -391,7 +391,6 @@ void LLAgentWearables::saveWearable(const EWearableType type, const U32 index, B } } -// MULTI-WEARABLE: add index void LLAgentWearables::saveWearableAs(const EWearableType type, const U32 index, const std::string& new_name, @@ -417,7 +416,7 @@ void LLAgentWearables::saveWearableAs(const EWearableType type, } std::string trunc_name(new_name); LLStringUtil::truncate(trunc_name, DB_INV_ITEM_NAME_STR_LEN); - LLWearable* new_wearable = LLWearableList::instance().createCopyFromAvatar( + LLWearable* new_wearable = LLWearableList::instance().createCopy( old_wearable, trunc_name); LLPointer<LLInventoryCallback> cb = @@ -451,10 +450,8 @@ void LLAgentWearables::saveWearableAs(const EWearableType type, void LLAgentWearables::revertWearable(const EWearableType type, const U32 index) { LLWearable* wearable = getWearable(type, index); - if (wearable) - { - wearable->writeToAvatar(TRUE); - } + wearable->revertValues(); + gAgent.sendAgentSetAppearance(); } @@ -604,13 +601,10 @@ void LLAgentWearables::sendAgentWearablesRequest() 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; + return (gAgentWearables.getWearableCount(type) > 0); } LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index) @@ -633,6 +627,11 @@ LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index) void LLAgentWearables::setWearable(const EWearableType type, U32 index, LLWearable *wearable) { + if (!getWearable(type,index)) + { + pushWearable(type,wearable); + return; + } wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); if (wearable_iter == mWearableDatas.end()) { @@ -650,6 +649,59 @@ void LLAgentWearables::setWearable(const EWearableType type, U32 index, LLWearab } } +U32 LLAgentWearables::pushWearable(const EWearableType type, LLWearable *wearable) +{ + if (wearable == NULL) + { + // no null wearables please! + //TODO: insert llwarns + return MAX_WEARABLES_PER_TYPE; + } + if (type < WT_COUNT || mWearableDatas[type].size() < MAX_WEARABLES_PER_TYPE) + { + mWearableDatas[type].push_back(wearable); + return mWearableDatas[type].size()-1; + } + return MAX_WEARABLES_PER_TYPE; +} + +void LLAgentWearables::popWearable(const EWearableType type, LLWearable *wearable) +{ + U32 index = getWearableIndex(type, wearable); + if (index < MAX_WEARABLES_PER_TYPE && index < getWearableCount(type)) + { + popWearable(type, index); + } +} + +void LLAgentWearables::popWearable(const EWearableType type, U32 index) +{ + if (getWearable(type, index)) + { + mWearableDatas[type].erase(mWearableDatas[type].begin() + index); + } +} + +U32 LLAgentWearables::getWearableIndex(const EWearableType type, LLWearable *wearable) +{ + wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); + if (wearable_iter == mWearableDatas.end()) + { + llwarns << "tried to get wearable index with an invalid type!" << llendl; + return MAX_WEARABLES_PER_TYPE; + } + const wearableentry_vec_t& wearable_vec = wearable_iter->second; + for(U32 index = 0; index < wearable_vec.size(); index++) + { + if (wearable_vec[index] == wearable) + { + return index; + } + } + + return MAX_WEARABLES_PER_TYPE; +} + const LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index) const { wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); @@ -668,7 +720,17 @@ const LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 in } } -//MULTI-WEARABLE: this will give wrong values until we get rid of the "always one empty object" scheme. +LLWearable* LLAgentWearables::getTopWearable(const EWearableType type) +{ + U32 count = getWearableCount(type); + if ( count == 0) + { + return NULL; + } + + return getWearable(type, count-1); +} + U32 LLAgentWearables::getWearableCount(const EWearableType type) const { wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); @@ -680,6 +742,13 @@ U32 LLAgentWearables::getWearableCount(const EWearableType type) const return wearable_vec.size(); } +U32 LLAgentWearables::getWearableCount(const U32 tex_index) const +{ + const EWearableType wearable_type = LLVOAvatarDictionary::getTEWearableType((LLVOAvatarDefines::ETextureIndex)tex_index); + return getWearableCount(wearable_type); +} + + BOOL LLAgentWearables::itemUpdatePending(const LLUUID& item_id) const { return mItemsAwaitingWearableUpdate.find(item_id) != mItemsAwaitingWearableUpdate.end(); @@ -798,7 +867,7 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs // 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 + LLInitialWearablesFetch::InitialWearableData wearable_data(type, item_id, asset_id); // MULTI-WEARABLE: update outfit->mAgentInitialWearables.push_back(wearable_data); } @@ -832,7 +901,7 @@ void LLAgentWearables::onInitialWearableAssetArrived(LLWearable* wearable, void* { boost::scoped_ptr<LLInitialWearablesFetch::InitialWearableData> wear_data((LLInitialWearablesFetch::InitialWearableData*)userdata); const EWearableType type = wear_data->mType; - const U32 index = wear_data->mIndex; + U32 index = 0; LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); if (!avatar) @@ -843,22 +912,19 @@ void LLAgentWearables::onInitialWearableAssetArrived(LLWearable* wearable, void* 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); + index = gAgentWearables.pushWearable(type, 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); } @@ -898,7 +964,7 @@ void LLAgentWearables::recoverMissingWearable(const EWearableType type, U32 inde S32 type_s32 = (S32) type; setWearable(type,index,new_wearable); - new_wearable->writeToAvatar(TRUE); + //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 @@ -938,8 +1004,8 @@ void LLAgentWearables::addLocalTextureObject(const EWearableType wearable_type, { 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()); + LLLocalTextureObject* lto = new LLLocalTextureObject(); + wearable->setLocalTextureObject(texture_type, lto); } void LLAgentWearables::createStandardWearables(BOOL female) @@ -982,17 +1048,15 @@ void LLAgentWearables::createStandardWearables(BOOL female) once = true; donecb = new createStandardWearablesAllDoneCallback; } - // MULTI_WEARABLE: only elt 0, may be the right thing? - llassert(getWearable((EWearableType)i,0) == NULL); + llassert(getWearableCount((EWearableType)i) == 0); LLWearable* wearable = LLWearableList::instance().createNewWearable((EWearableType)i); - setWearable((EWearableType)i,0,wearable); + U32 index = pushWearable((EWearableType)i,wearable); // no need to update here... - // MULTI_WEARABLE: hardwired index = 0 here. LLPointer<LLInventoryCallback> cb = new addWearableToAgentInventoryCallback( donecb, i, - 0, + index, wearable, addWearableToAgentInventoryCallback::CALL_CREATESTANDARDDONE); addWearableToAgentInventory(cb, wearable, LLUUID::null, FALSE); @@ -1002,11 +1066,9 @@ void LLAgentWearables::createStandardWearables(BOOL female) void LLAgentWearables::createStandardWearablesDone(S32 type, U32 index) { - LLWearable* wearable = getWearable((EWearableType)type, index); - - if (wearable) + if (mAvatarObject) { - wearable->writeToAvatar(TRUE); + mAvatarObject->updateVisualParams(); } } @@ -1023,12 +1085,12 @@ void LLAgentWearables::createStandardWearablesAllDone() mAvatarObject->onFirstTEMessageReceived(); } +// MULTI-WEARABLE: Properly handle multiwearables later. 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) + if (getWearableCount( (EWearableType) i) != 0 ) { wearables.push_back(i); } @@ -1141,25 +1203,30 @@ void LLAgentWearables::makeNewOutfit(const std::string& new_folder_name, 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) + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) { - 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); + LLViewerObject *attached_object = (*attachment_iter); + if(!attached_object) continue; + const LLUUID& item_id = (*attachment_iter)->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()); } - msg->nextBlock("ObjectData"); - msg->addUUID("OldItemID", item_id); - msg->addUUID("OldFolderID", item->getParentUUID()); } if (msg_started) @@ -1233,6 +1300,13 @@ void LLAgentWearables::addWearableToAgentInventory(LLPointer<LLInventoryCallback void LLAgentWearables::removeWearable(const EWearableType type, bool do_remove_all, U32 index) { + if ((gAgent.isTeen()) + && (type == WT_UNDERSHIRT || type == WT_UNDERPANTS)) + { + // Can't take off underclothing in simple UI mode or on PG accounts + // TODO: enable the removing of a single undershirt/underpants if multiple are worn. - Nyx + return; + } if (do_remove_all) { @@ -1240,16 +1314,8 @@ void LLAgentWearables::removeWearable(const EWearableType type, bool do_remove_a } 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()) @@ -1308,26 +1374,22 @@ void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_rem { LLWearable* old_wearable = getWearable(type,i); gInventory.addChangedMask(LLInventoryObserver::LABEL, getWearableItemID(type,i)); - setWearable(type,i,NULL); + popWearable(type,i); //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); } } + mWearableDatas[type].clear(); } else { LLWearable* old_wearable = getWearable(type, index); gInventory.addChangedMask(LLInventoryObserver::LABEL, getWearableItemID(type,index)); - setWearable(type,index,NULL); + popWearable(type, index); //queryWearableCache(); // moved below @@ -1335,16 +1397,6 @@ void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_rem { 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(); @@ -1429,7 +1481,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it { wearables_being_removed.push_back(wearable); } - setWearable((EWearableType)i,0,NULL); + removeWearable((EWearableType)i,true,0); } } @@ -1450,9 +1502,9 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it } } - for (i = 0; i < count; i++) + if (mAvatarObject) { - wearables[i]->writeToAvatar(TRUE); + mAvatarObject->updateVisualParams(); } // Start rendering & update the server @@ -1578,7 +1630,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n //llinfos << "LLVOAvatar::setWearableItem()" << llendl; queryWearableCache(); - new_wearable->writeToAvatar(TRUE); + //new_wearable->writeToAvatar(TRUE); updateServer(); } @@ -1612,13 +1664,16 @@ void LLAgentWearables::queryWearableCache() 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) + // MULTI_WEARABLE: not order-dependent + const U32 num_wearables = getWearableCount(baked_type); + for (U32 index = 0; index < num_wearables; ++index) { - hash ^= wearable->getAssetID(); + const LLWearable* wearable = getWearable(baked_type,index); + if (wearable) + { + hash ^= wearable->getAssetID(); + } } } if (hash.notNull()) @@ -1672,7 +1727,6 @@ void LLAgentWearables::userRemoveAllClothes(void* userdata) } // static -// MULTI_WEARABLE: removing all here. void LLAgentWearables::userRemoveAllClothesStep2(BOOL proceed) { if (proceed) @@ -1717,20 +1771,25 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj { LLVOAvatar::attachment_map_t::iterator curiter = iter++; LLViewerJointAttachment* attachment = curiter->second; - LLViewerObject* objectp = attachment->getObject(); - if (objectp) + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) { - LLUUID object_item_id = attachment->getItemID(); - if (requested_item_ids.find(object_item_id) != requested_item_ids.end()) + LLViewerObject *objectp = (*attachment_iter); + if (objectp) { - // Object currently worn, was requested. - // Flag as currently worn so we won't have to add it again. - current_item_ids.insert(object_item_id); - } - else - { - // object currently worn, not requested. - objects_to_remove.push_back(objectp); + LLUUID object_item_id = objectp->getItemID(); + if (requested_item_ids.find(object_item_id) != requested_item_ids.end()) + { + // Object currently worn, was requested. + // Flag as currently worn so we won't have to add it again. + current_item_ids.insert(object_item_id); + } + else + { + // object currently worn, not requested. + objects_to_remove.push_back(objectp); + } } } } @@ -1806,9 +1865,16 @@ void LLAgentWearables::userRemoveAllAttachments() { LLVOAvatar::attachment_map_t::iterator curiter = iter++; LLViewerJointAttachment* attachment = curiter->second; - LLViewerObject* objectp = attachment->getObject(); - if (objectp) - objects_to_remove.push_back(objectp); + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject *attached_object = (*attachment_iter); + if (attached_object) + { + objects_to_remove.push_back(attached_object); + } + } } userRemoveMultipleAttachments(objects_to_remove); } diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 8b9d29342a..6b456abfa7 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -45,6 +45,7 @@ class LLVOAvatarSelf; class LLWearable; class LLInitialWearablesFetch; class LLViewerObject; +class LLTexLayerTemplate; class LLAgentWearables { @@ -93,8 +94,9 @@ public: 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; - + LLWearable* getTopWearable(const EWearableType type); + U32 getWearableCount(const EWearableType type) const; + U32 getWearableCount(const U32 tex_index) const; //-------------------------------------------------------------------- // Setters @@ -103,12 +105,16 @@ public: private: // Low-level data structure setter - public access is via setWearableItem, etc. void setWearable(const EWearableType type, U32 index, LLWearable *wearable); + U32 pushWearable(const EWearableType type, LLWearable *wearable); + void popWearable(const EWearableType type, LLWearable *wearable); + void popWearable(const EWearableType type, U32 index); 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); + U32 getWearableIndex(const EWearableType type, LLWearable *wearable); protected: void setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append = false); static bool onSetWearableDialog(const LLSD& notification, const LLSD& response, LLWearable* wearable); @@ -252,6 +258,8 @@ private: LLPointer<LLRefCount> mCB; }; + static const U32 MAX_WEARABLES_PER_TYPE = 1; + }; // LLAgentWearables extern LLAgentWearables gAgentWearables; diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index cf8d852dfe..0cf28f590a 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -418,11 +418,7 @@ void removeDuplicateItems(LLInventoryModel::item_array_t& dst, const LLInventory if (!append && total_links > 0) { - for (S32 i = 0; i < cof_items.count(); ++i) - { - gInventory.purgeObject(cof_items.get(i)->getUUID()); - } - gInventory.notifyObservers(); + purgeCOFBeforeRebuild(category); } LLPointer<LLUpdateAppearanceOnDestroy> link_waiter = new LLUpdateAppearanceOnDestroy; @@ -521,6 +517,68 @@ void removeDuplicateItems(LLInventoryModel::item_array_t& dst, const LLInventory } } +/* static */ bool LLAppearanceManager::isMandatoryWearableType(EWearableType type) +{ + return (type==WT_SHAPE) || (type==WT_SKIN) || (type== WT_HAIR) || (type==WT_EYES); +} + +// For mandatory body parts. +/* static */ void LLAppearanceManager::checkMandatoryWearableTypes(const LLUUID& category, std::set<EWearableType>& types_found) +{ + LLInventoryModel::cat_array_t new_cats; + LLInventoryModel::item_array_t new_items; + gInventory.collectDescendents(category, new_cats, new_items, + LLInventoryModel::EXCLUDE_TRASH); + std::set<EWearableType> wt_types_found; + for (S32 i = 0; i < new_items.count(); ++i) + { + LLViewerInventoryItem *itemp = new_items.get(i); + if (itemp->isWearableType()) + { + EWearableType type = itemp->getWearableType(); + if (isMandatoryWearableType(type)) + { + types_found.insert(type); + } + } + } +} + +// Remove everything from the COF that we safely can before replacing +// with contents of new category. This means preserving any mandatory +// body parts that aren't present in the new category, and getting rid +// of everything else. +/* static */ void LLAppearanceManager::purgeCOFBeforeRebuild(const LLUUID& category) +{ + // See which mandatory body types are present in the new category. + std::set<EWearableType> wt_types_found; + checkMandatoryWearableTypes(category,wt_types_found); + + LLInventoryModel::cat_array_t cof_cats; + LLInventoryModel::item_array_t cof_items; + gInventory.collectDescendents(getCOF(), cof_cats, cof_items, + LLInventoryModel::EXCLUDE_TRASH); + for (S32 i = 0; i < cof_items.count(); ++i) + { + LLViewerInventoryItem *itemp = cof_items.get(i); + if (itemp->isWearableType()) + { + EWearableType type = itemp->getWearableType(); + if (!isMandatoryWearableType(type) || (wt_types_found.find(type) != wt_types_found.end())) + { + // Not mandatory or supplied by the new category - OK to delete + gInventory.purgeObject(cof_items.get(i)->getUUID()); + } + } + else + { + // Not a wearable - always purge + gInventory.purgeObject(cof_items.get(i)->getUUID()); + } + } + gInventory.notifyObservers(); +} + // Replace COF contents from a given outfit folder. /* static */ void LLAppearanceManager::rebuildCOFFromOutfit(const LLUUID& category) { @@ -539,29 +597,17 @@ void removeDuplicateItems(LLInventoryModel::item_array_t& dst, const LLInventory return; } - const LLUUID ¤t_outfit_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT); // Processes that take time should show the busy cursor //inc_busy_count(); - LLInventoryModel::cat_array_t cof_cats; - LLInventoryModel::item_array_t cof_items; - gInventory.collectDescendents(current_outfit_id, cof_cats, cof_items, - LLInventoryModel::EXCLUDE_TRASH); - //dumpCat(current_outfit_id,"COF before remove:"); - if (items.count() > 0) - { - for (S32 i = 0; i < cof_items.count(); ++i) - { - gInventory.purgeObject(cof_items.get(i)->getUUID()); - } - gInventory.notifyObservers(); - } - //dumpCat(current_outfit_id,"COF after remove:"); + purgeCOFBeforeRebuild(category); + LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy; + LLUUID current_outfit_id = getCOF(); LLAppearanceManager::shallowCopyCategory(category, current_outfit_id, link_waiter); //dumpCat(current_outfit_id,"COF after shallow copy:"); @@ -907,6 +953,7 @@ void LLAppearanceManager::wearItem( LLInventoryItem* item, bool do_update ) /* static */ void LLAppearanceManager::wearEnsemble( LLInventoryCategory* cat, bool do_update ) { +#if SUPPORT_ENSEMBLES // BAP add check for already in COF. LLPointer<LLInventoryCallback> cb = do_update ? new ModifiedCOFCallback : 0; link_inventory_item( gAgent.getID(), @@ -915,6 +962,7 @@ void LLAppearanceManager::wearEnsemble( LLInventoryCategory* cat, bool do_update cat->getName(), LLAssetType::AT_LINK_FOLDER, cb); +#endif } /* static */ diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index fe24696182..928b5f2bcd 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -78,6 +78,11 @@ private: bool follow_folder_links); static void onWearableAssetFetch(LLWearable* wearable, void* data); static void updateAgentWearables(LLWearableHoldingPattern* holder, bool append); + static bool isMandatoryWearableType(EWearableType type); + static void checkMandatoryWearableTypes(const LLUUID& category, std::set<EWearableType>& types_found); + static void purgeCOFBeforeRebuild(const LLUUID& category); }; +#define SUPPORT_ENSEMBLES 0 + #endif diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp index 3e411583ac..7ae1b5cd4a 100644 --- a/indra/newview/llavatariconctrl.cpp +++ b/indra/newview/llavatariconctrl.cpp @@ -181,16 +181,6 @@ LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p) 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); @@ -239,16 +229,13 @@ void LLAvatarIconCtrl::setValue(const LLSD& value) mAvatarId = value.asUUID(); // *BUG: This will return stale icons if a user changes their - // profile picture. Also, the online/offline tooltips will be - // out of date. However, otherwise we send too many upstream + // profile picture. However, otherwise we send too many upstream // AvatarPropertiesRequest messages. - // - // *TODO: Implement a timeout on the icon cache, perhaps a day?, - // and make the cache update if a user views the full-profile for - // an avatar. + + // to get fresh avatar icon use + // LLAvatarIconIDCache::getInstance()->remove(avatar_id); // Check if cache already contains image_id for that avatar - if (!updateFromCache()) { app->addObserver(mAvatarId, this); @@ -282,36 +269,6 @@ bool LLAvatarIconCtrl::updateFromCache() LLIconCtrl::setValue("default_profile_picture.j2c"); } - // Can only see online status of friends - if (LLAvatarTracker::instance().isBuddy(mAvatarId)) - { - if (LLAvatarTracker::instance().isBuddyOnline(mAvatarId)) - { - // Update color of status symbol and tool tip - mStatusSymbol->setColor(LLColor4::green); - if (mDrawTooltip) - { - setToolTip((LLStringExplicit)"Online"); - } - } - else - { - mStatusSymbol->setColor(LLColor4::grey); - if (mDrawTooltip) - { - setToolTip((LLStringExplicit)"Offline"); - } - } - } - else - { - // Not a buddy, no information - mStatusSymbol->setColor(LLColor4::grey); - if (mDrawTooltip) - { - setToolTip((LLStringExplicit)""); - } - } return true; } @@ -370,6 +327,11 @@ void LLAvatarIconCtrl::nameUpdatedCallback( { mFirstName = first; mLastName = last; + + if (mDrawTooltip) + { + setToolTip(mFirstName + " " + mLastName); + } } } diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h index 77390eb233..426fcec514 100644 --- a/indra/newview/llavatariconctrl.h +++ b/indra/newview/llavatariconctrl.h @@ -104,7 +104,6 @@ public: const std::string& getLastName() const { return mLastName; } protected: - LLIconCtrl* mStatusSymbol; LLUUID mAvatarId; std::string mFirstName; std::string mLastName; diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 36f9780ad0..ef48420490 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -202,6 +202,7 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is item->showSpeakingIndicator(true); item->setName(name); item->setAvatarId(id); + item->setOnline(is_bold); item->setContextMenu(mContextMenu); item->childSetVisible("info_btn", false); diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index 4179d7a58d..90408beca0 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -52,11 +52,17 @@ LLAvatarListItem::LLAvatarListItem() mInfoBtn(NULL), mProfileBtn(NULL), mContextMenu(NULL), - mAvatarId(LLUUID::null) + mOnlineStatus(E_UNKNOWN) { LLUICtrlFactory::getInstance()->buildPanel(this, "panel_avatar_list_item.xml"); } +LLAvatarListItem::~LLAvatarListItem() +{ + if (mAvatarId.notNull()) + LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarId, this); +} + BOOL LLAvatarListItem::postBuild() { mAvatarIcon = getChild<LLAvatarIconCtrl>("avatar_icon"); @@ -138,6 +144,36 @@ void LLAvatarListItem::setStatus(const std::string& status) mStatus->setValue(status); } +// virtual, called by LLAvatarTracker +void LLAvatarListItem::changed(U32 mask) +{ + // no need to check mAvatarId for null in this case + setOnline(LLAvatarTracker::instance().isBuddyOnline(mAvatarId)); +} + +void LLAvatarListItem::setOnline(bool online) +{ + // *FIX: setName() overrides font style set by setOnline(). Not an issue ATM. + // *TODO: Make the colors configurable via XUI. + + if (mOnlineStatus != E_UNKNOWN && (bool) mOnlineStatus == online) + return; + + mOnlineStatus = (EOnlineStatus) online; + + // Change avatar name font style depending on the new online status. + LLStyle::Params style_params; + style_params.color = online ? LLColor4::white : LLColor4::grey; + + // Rebuild the text to change its style. + std::string text = mAvatarName->getText(); + mAvatarName->setText(LLStringUtil::null); + mAvatarName->appendText(text, false, style_params); + + // Make the icon fade if the avatar goes offline. + mAvatarIcon->setColor(online ? LLColor4::white : LLColor4::smoke); +} + void LLAvatarListItem::setName(const std::string& name) { mAvatarName->setValue(name); @@ -146,10 +182,17 @@ void LLAvatarListItem::setName(const std::string& name) void LLAvatarListItem::setAvatarId(const LLUUID& id) { + if (mAvatarId.notNull()) + LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarId, this); + mAvatarId = id; mAvatarIcon->setValue(id); mSpeakingIndicator->setSpeakerId(id); + // We'll be notified on avatar online status changes + if (mAvatarId.notNull()) + LLAvatarTracker::instance().addParticularFriendObserver(mAvatarId, this); + // Set avatar name. gCacheName->get(id, FALSE, boost::bind(&LLAvatarListItem::onNameCache, this, _2, _3)); } diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index 871441b2d3..2330db5249 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -38,9 +38,11 @@ #include "llbutton.h" #include "lltextbox.h" +#include "llcallingcard.h" // for LLFriendObserver + class LLAvatarIconCtrl; -class LLAvatarListItem : public LLPanel +class LLAvatarListItem : public LLPanel, public LLFriendObserver { public: class ContextMenu @@ -50,15 +52,17 @@ public: }; LLAvatarListItem(); - virtual ~LLAvatarListItem() {}; + virtual ~LLAvatarListItem(); virtual BOOL postBuild(); virtual void onMouseLeave(S32 x, S32 y, MASK mask); virtual void onMouseEnter(S32 x, S32 y, MASK mask); virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); virtual void setValue(const LLSD& value); + virtual void changed(U32 mask); // from LLFriendObserver void setStatus(const std::string& status); + void setOnline(bool online); void setName(const std::string& name); void setAvatarId(const LLUUID& id); @@ -75,6 +79,13 @@ public: void setContextMenu(ContextMenu* menu) { mContextMenu = menu; } private: + + typedef enum e_online_status { + E_OFFLINE, + E_ONLINE, + E_UNKNOWN, + } EOnlineStatus; + void onNameCache(const std::string& first_name, const std::string& last_name); LLAvatarIconCtrl*mAvatarIcon; @@ -87,6 +98,7 @@ private: ContextMenu* mContextMenu; LLUUID mAvatarId; + EOnlineStatus mOnlineStatus; }; #endif //LL_LLAVATARLISTITEM_H diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index 0ff8ca7d26..8987f14e97 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -185,6 +185,18 @@ void LLBottomTray::sessionRemoved(const LLUUID& session_id) } } +void LLBottomTray::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) +{ + //this is only needed in case of outgoing ad-hoc/group chat sessions + LLChicletPanel* chiclet_panel = getChicletPanel(); + if (chiclet_panel) + { + //it should be ad-hoc im chiclet or group im chiclet + LLChiclet* chiclet = chiclet_panel->findChiclet<LLChiclet>(old_session_id); + if (chiclet) chiclet->setSessionId(new_session_id); + } +} + //virtual void LLBottomTray::onFocusLost() { diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h index 4724c5ecef..cc35e63524 100644 --- a/indra/newview/llbottomtray.h +++ b/indra/newview/llbottomtray.h @@ -67,6 +67,7 @@ public: // 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); + void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id); virtual void onFocusLost(); virtual void setVisible(BOOL visible); diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 2b7bd83ca3..7a81d0c4a1 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -260,7 +260,7 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds) ++new_buddy_count; mBuddyInfo[agent_id] = (*itr).second; gCacheName->getName(agent_id, first, last); - mModifyMask |= LLFriendObserver::ADD; + addChangedMask(LLFriendObserver::ADD, agent_id); lldebugs << "Added buddy " << agent_id << ", " << (mBuddyInfo[agent_id]->isOnline() ? "Online" : "Offline") << ", TO: " << mBuddyInfo[agent_id]->getRightsGrantedTo() @@ -333,7 +333,7 @@ void LLAvatarTracker::setBuddyOnline(const LLUUID& id, bool is_online) if(info) { info->online(is_online); - mModifyMask |= LLFriendObserver::ONLINE; + addChangedMask(LLFriendObserver::ONLINE, id); lldebugs << "Set buddy " << id << (is_online ? " Online" : " Offline") << llendl; } else @@ -488,10 +488,52 @@ void LLAvatarTracker::notifyObservers() { (*it)->changed(mModifyMask); } + + for (changed_buddy_t::iterator it = mChangedBuddyIDs.begin(); it != mChangedBuddyIDs.end(); it++) + { + notifyParticularFriendObservers(*it); + } + mModifyMask = LLFriendObserver::NONE; mChangedBuddyIDs.clear(); } +void LLAvatarTracker::addParticularFriendObserver(const LLUUID& buddy_id, LLFriendObserver* observer) +{ + if (buddy_id.notNull() && observer) + mParticularFriendObserverMap[buddy_id].insert(observer); +} + +void LLAvatarTracker::removeParticularFriendObserver(const LLUUID& buddy_id, LLFriendObserver* observer) +{ + if (buddy_id.isNull() || !observer) + return; + + observer_map_t::iterator obs_it = mParticularFriendObserverMap.find(buddy_id); + if(obs_it == mParticularFriendObserverMap.end()) + return; + + obs_it->second.erase(observer); + + // purge empty sets from the map + if (obs_it->second.size() == 0) + mParticularFriendObserverMap.erase(obs_it); +} + +void LLAvatarTracker::notifyParticularFriendObservers(const LLUUID& buddy_id) +{ + observer_map_t::iterator obs_it = mParticularFriendObserverMap.find(buddy_id); + if(obs_it == mParticularFriendObserverMap.end()) + return; + + // Notify observers interested in buddy_id. + observer_set_t& obs = obs_it->second; + for (observer_set_t::iterator ob_it = obs.begin(); ob_it != obs.end(); ob_it++) + { + (*ob_it)->changed(mModifyMask); + } +} + // store flag for change // and id of object change applies to void LLAvatarTracker::addChangedMask(U32 mask, const LLUUID& referent) @@ -610,8 +652,8 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg) } } } - mModifyMask |= LLFriendObserver::POWERS; + addChangedMask(LLFriendObserver::POWERS, agent_id); notifyObservers(); } @@ -684,10 +726,11 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) if (!notifyMsg.empty()) { floater->addHistoryLine(notifyMsg,LLUIColorTable::instance().getColor("SystemChatColor")); - - LLIMModel::getInstance()->addMessage(session_id, SYSTEM_FROM, LLUUID::null, notifyMsg); } } + + //*TODO instead of adding IM message about online/offline status + //do something like graying avatar icon on messages from a user that went offline, and make it colored when online. } mModifyMask |= LLFriendObserver::ONLINE; diff --git a/indra/newview/llcallingcard.h b/indra/newview/llcallingcard.h index 228239b5ba..bd58b2fbe6 100644 --- a/indra/newview/llcallingcard.h +++ b/indra/newview/llcallingcard.h @@ -150,6 +150,12 @@ public: void removeObserver(LLFriendObserver* observer); void notifyObservers(); + // Observers interested in updates of a particular avatar. + // On destruction these observers are NOT deleted. + void addParticularFriendObserver(const LLUUID& buddy_id, LLFriendObserver* observer); + void removeParticularFriendObserver(const LLUUID& buddy_id, LLFriendObserver* observer); + void notifyParticularFriendObservers(const LLUUID& buddy_id); + /** * Stores flag for change and id of object change applies to * @@ -199,6 +205,10 @@ protected: typedef std::vector<LLFriendObserver*> observer_list_t; observer_list_t mObservers; + typedef std::set<LLFriendObserver*> observer_set_t; + typedef std::map<LLUUID, observer_set_t> observer_map_t; + observer_map_t mParticularFriendObserverMap; + private: // do not implement LLAvatarTracker(const LLAvatarTracker&); diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp new file mode 100644 index 0000000000..80f3867a80 --- /dev/null +++ b/indra/newview/llchathistory.cpp @@ -0,0 +1,126 @@ +/** + * @file llchathistory.cpp + * @brief LLTextEditor 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 "llchathistory.h" +#include "llpanel.h" +#include "lltextbox.h" +#include "lluictrlfactory.h" +#include "llscrollcontainer.h" +#include "llavatariconctrl.h" + +static LLDefaultChildRegistry::Register<LLChatHistory> r("chat_history"); +static const std::string MESSAGE_USERNAME_DATE_SEPARATOR(" ----- "); + +LLChatHistory::LLChatHistory(const LLChatHistory::Params& p) +: LLTextEditor(p), +mMessageHeaderFilename(p.message_header), +mMessageSeparatorFilename(p.message_separator), +mLeftTextPad(p.left_text_pad), +mRightTextPad(p.right_text_pad), +mLeftWidgetPad(p.left_widget_pad), +mRightWidgetPad(p.rigth_widget_pad) +{ +} + +LLChatHistory::~LLChatHistory() +{ + this->clear(); +} + +/*void LLChatHistory::updateTextRect() +{ + static LLUICachedControl<S32> texteditor_border ("UITextEditorBorder", 0); + + LLRect old_text_rect = mTextRect; + mTextRect = mScroller->getContentWindowRect(); + mTextRect.stretch(-texteditor_border); + mTextRect.mLeft += mLeftTextPad; + mTextRect.mRight -= mRightTextPad; + if (mTextRect != old_text_rect) + { + needsReflow(); + } +}*/ + +LLView* LLChatHistory::getSeparator() +{ + LLPanel* separator = LLUICtrlFactory::getInstance()->createFromFile<LLPanel>(mMessageSeparatorFilename, NULL, LLPanel::child_registry_t::instance()); + return separator; +} + +LLView* LLChatHistory::getHeader(const LLUUID& avatar_id, std::string& from, std::string& time) +{ + LLPanel* header = LLUICtrlFactory::getInstance()->createFromFile<LLPanel>(mMessageHeaderFilename, NULL, LLPanel::child_registry_t::instance()); + LLTextBox* userName = header->getChild<LLTextBox>("user_name"); + userName->setValue(from); + LLTextBox* timeBox = header->getChild<LLTextBox>("time_box"); + timeBox->setValue(time); + if(!avatar_id.isNull()) + { + LLAvatarIconCtrl* icon = header->getChild<LLAvatarIconCtrl>("avatar_icon"); + icon->setValue(avatar_id); + } + return header; +} + +void LLChatHistory::appendWidgetMessage(const LLUUID& avatar_id, std::string& from, std::string& time, std::string& message, LLStyle::Params& style_params) +{ + LLView* view = NULL; + std::string view_text; + + if (mLastFromName == from) + { + view = getSeparator(); + view_text = "\n"; + } + else + { + view = getHeader(avatar_id, from, time); + view_text = from + MESSAGE_USERNAME_DATE_SEPARATOR + time; + } + //Prepare the rect for the view + LLRect target_rect = mScroller->getContentWindowRect(); + target_rect.mLeft += mLeftWidgetPad; + target_rect.mRight -= mRightWidgetPad; + view->reshape(target_rect.getWidth(), view->getRect().getHeight()); + view->setOrigin(target_rect.mLeft, view->getRect().mBottom); + + this->appendWidget(view, view_text, FALSE, TRUE); + + //Append the text message + this->appendText(message, TRUE, style_params); + + mLastFromName = from; + this->blockUndo(); + this->setCursorAndScrollToEnd(); +} diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h new file mode 100644 index 0000000000..d6eccf896a --- /dev/null +++ b/indra/newview/llchathistory.h @@ -0,0 +1,112 @@ +/** + * @file llchathistory.h + * @brief LLTextEditor 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 LLCHATHISTORY_H_ +#define LLCHATHISTORY_H_ + +#include "lltexteditor.h" + +//Chat log widget allowing addition of a message as a widget +class LLChatHistory : public LLTextEditor +{ + public: + struct Params : public LLInitParam::Block<Params, LLTextEditor::Params> + { + //Message header filename + Optional<std::string> message_header; + //Message separator filename + Optional<std::string> message_separator; + //Text left padding from the scroll rect + Optional<S32> left_text_pad; + //Text right padding from the scroll rect + Optional<S32> right_text_pad; + //Widget left padding from the scroll rect + Optional<S32> left_widget_pad; + //Widget right padding from the scroll rect + Optional<S32> rigth_widget_pad; + + Params() + : message_header("message_header"), + message_separator("message_separator"), + left_text_pad("left_text_pad"), + right_text_pad("right_text_pad"), + left_widget_pad("left_widget_pad"), + rigth_widget_pad("rigth_widget_pad") + { + } + + }; + protected: + LLChatHistory(const Params&); + friend class LLUICtrlFactory; + + /** + * Redefinition of LLTextEditor::updateTextRect() to considerate text + * left/right padding params. + */ + //virtual void updateTextRect(); + /** + * Builds a message separator. + * @return pointer to LLView separator object. + */ + LLView* getSeparator(); + /** + * Builds a message header. + * @param from owner of a message. + * @param time time of a message. + * @return pointer to LLView header object. + */ + LLView* getHeader(const LLUUID& avatar_id, std::string& from, std::string& time); + + public: + ~LLChatHistory(); + + /** + * Appends a widget message. + * If last user appended message, concurs with current user, + * separator is added before the message, otherwise header is added. + * @param from owner of a message. + * @param time time of a message. + * @param message message itself. + */ + void appendWidgetMessage(const LLUUID& avatar_id, std::string& from, std::string& time, std::string& message, LLStyle::Params& style_params); + + private: + std::string mLastFromName; + std::string mMessageHeaderFilename; + std::string mMessageSeparatorFilename; + S32 mLeftTextPad; + S32 mRightTextPad; + S32 mLeftWidgetPad; + S32 mRightWidgetPad; +}; +#endif /* LLCHATHISTORY_H_ */ diff --git a/indra/newview/lldriverparam.cpp b/indra/newview/lldriverparam.cpp index 55b3ab796e..e7295512c1 100644 --- a/indra/newview/lldriverparam.cpp +++ b/indra/newview/lldriverparam.cpp @@ -36,6 +36,9 @@ #include "llfasttimer.h" #include "llvoavatar.h" +#include "llvoavatarself.h" +#include "llagent.h" +#include "llwearable.h" //----------------------------------------------------------------------------- // LLDriverParamInfo @@ -100,12 +103,66 @@ BOOL LLDriverParamInfo::parseXml(LLXmlTreeNode* node) return TRUE; } +//virtual +void LLDriverParamInfo::toStream(std::ostream &out) +{ + LLViewerVisualParamInfo::toStream(out); + out << "driver" << "\t"; + out << mDrivenInfoList.size() << "\t"; + for (entry_info_list_t::iterator iter = mDrivenInfoList.begin(); iter != mDrivenInfoList.end(); iter++) + { + LLDrivenEntryInfo driven = *iter; + out << driven.mDrivenID << "\t"; + } + + out << std::endl; + + LLVOAvatarSelf *avatar = gAgent.getAvatarObject(); + if(avatar) + { + for (entry_info_list_t::iterator iter = mDrivenInfoList.begin(); iter != mDrivenInfoList.end(); iter++) + { + LLDrivenEntryInfo driven = *iter; + LLViewerVisualParam *param = (LLViewerVisualParam*)avatar->getVisualParam(driven.mDrivenID); + if (param) + { + param->getInfo()->toStream(out); + if (param->getWearableType() != mWearableType) + { + if(param->getCrossWearable()) + { + out << "cross-wearable" << "\t"; + } + else + { + out << "ERROR!" << "\t"; + } + } + else + { + out << "valid" << "\t"; + } + } + else + { + llwarns << "could not get parameter " << driven.mDrivenID << " from avatar " << avatar << " for driver parameter " << getID() << llendl; + } + out << std::endl; + } + } +} + //----------------------------------------------------------------------------- // LLDriverParam //----------------------------------------------------------------------------- LLDriverParam::LLDriverParam(LLVOAvatar *avatarp) - : mCurrentDistortionParam( NULL ), mAvatarp(avatarp) + : mCurrentDistortionParam( NULL ), mAvatarp(avatarp), mWearablep(NULL) +{ +} + +LLDriverParam::LLDriverParam(LLWearable *wearablep) + : mCurrentDistortionParam( NULL ), mAvatarp(NULL), mWearablep(wearablep) { } @@ -122,27 +179,48 @@ BOOL LLDriverParam::setInfo(LLDriverParamInfo *info) mID = info->mID; setWeight(getDefaultWeight(), FALSE ); - - LLDriverParamInfo::entry_info_list_t::iterator iter; - mDriven.reserve(getInfo()->mDrivenInfoList.size()); - for (iter = getInfo()->mDrivenInfoList.begin(); iter != getInfo()->mDrivenInfoList.end(); iter++) + + return TRUE; +} + +void LLDriverParam::setWearable(LLWearable *wearablep) +{ + if (wearablep) { - LLDrivenEntryInfo *driven_info = &(*iter); - S32 driven_id = driven_info->mDrivenID; - LLViewerVisualParam* param = (LLViewerVisualParam*)mAvatarp->getVisualParam( driven_id ); - if (param) + mWearablep = wearablep; + mAvatarp = NULL; + } +} + +void LLDriverParam::setAvatar(LLVOAvatar *avatarp) +{ + if (avatarp) + { + mWearablep = NULL; + mAvatarp = avatarp; + } +} + +/*virtual*/ LLViewerVisualParam * LLDriverParam::cloneParam(LLWearable* wearable) const +{ + LLDriverParam *new_param; + if (wearable) + { + new_param = new LLDriverParam(wearable); + } + else + { + if (mWearablep) { - mDriven.push_back(LLDrivenEntry( param, driven_info )); + new_param = new LLDriverParam(mWearablep); } else { - llerrs << "<driven> Unable to resolve driven parameter: " << driven_id << llendl; - mInfo = NULL; - return FALSE; + new_param = new LLDriverParam(mAvatarp); } } - - return TRUE; + *new_param = *this; + return new_param; } #if 0 // obsolete @@ -218,8 +296,8 @@ void LLDriverParam::setWeight(F32 weight, BOOL set_by_user) { driven_weight = driven_min; } - - driven->mParam->setWeight( driven_weight, set_by_user ); + + setDrivenWeight(driven,driven_weight,set_by_user); continue; } else @@ -243,13 +321,13 @@ void LLDriverParam::setWeight(F32 weight, BOOL set_by_user) driven_weight = driven_min; } - driven->mParam->setWeight( driven_weight, set_by_user ); + setDrivenWeight(driven,driven_weight,set_by_user); continue; } } driven_weight = getDrivenWeight(driven, mCurWeight); - driven->mParam->setWeight( driven_weight, set_by_user ); + setDrivenWeight(driven,driven_weight,set_by_user); } } @@ -402,6 +480,50 @@ void LLDriverParam::stopAnimating(BOOL set_by_user) } } +/*virtual*/ +BOOL LLDriverParam::linkDrivenParams(visual_param_mapper mapper, bool only_cross_params) +{ + BOOL success = TRUE; + LLDriverParamInfo::entry_info_list_t::iterator iter; + for (iter = getInfo()->mDrivenInfoList.begin(); iter != getInfo()->mDrivenInfoList.end(); ++iter) + { + LLDrivenEntryInfo *driven_info = &(*iter); + S32 driven_id = driven_info->mDrivenID; + + // check for already existing links. Do not overwrite. + BOOL found = FALSE; + for (entry_list_t::iterator driven_iter = mDriven.begin(); driven_iter != mDriven.end() && !found; ++driven_iter) + { + if (driven_iter->mInfo->mDrivenID == driven_id) + { + found = TRUE; + } + } + + if (!found) + { + LLViewerVisualParam* param = (LLViewerVisualParam*)mapper(driven_id); + bool push = param && (!only_cross_params || param->getCrossWearable()); + if (push) + { + mDriven.push_back(LLDrivenEntry( param, driven_info )); + } + else + { + success = FALSE; + } + } + } + + return success; +} + +void LLDriverParam::resetDrivenParams() +{ + mDriven.clear(); + mDriven.reserve(getInfo()->mDrivenInfoList.size()); +} + //----------------------------------------------------------------------------- // getDrivenWeight() //----------------------------------------------------------------------------- @@ -458,3 +580,18 @@ F32 LLDriverParam::getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight return driven_weight; } + +void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool set_by_user) +{ + LLVOAvatarSelf *avatar_self = gAgent.getAvatarObject(); + if(mWearablep && driven->mParam->getCrossWearable() && + mWearablep->isOnTop()) + { + // call setWeight through LLVOAvatarSelf so other wearables can be updated with the correct values + avatar_self->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, set_by_user ); + } + else + { + driven->mParam->setWeight( driven_weight, set_by_user ); + } +} diff --git a/indra/newview/lldriverparam.h b/indra/newview/lldriverparam.h index 7bc0c15448..c73e740574 100644 --- a/indra/newview/lldriverparam.h +++ b/indra/newview/lldriverparam.h @@ -36,6 +36,7 @@ #include "llviewervisualparam.h" class LLVOAvatar; +class LLWearable; //----------------------------------------------------------------------------- @@ -69,6 +70,8 @@ public: /*virtual*/ BOOL parseXml(LLXmlTreeNode* node); + /*virtual*/ void toStream(std::ostream &out); + protected: typedef std::deque<LLDrivenEntryInfo> entry_info_list_t; entry_info_list_t mDrivenInfoList; @@ -80,6 +83,7 @@ class LLDriverParam : public LLViewerVisualParam { public: LLDriverParam(LLVOAvatar *avatarp); + LLDriverParam(LLWearable *wearablep); ~LLDriverParam(); // Special: These functions are overridden by child classes @@ -87,12 +91,19 @@ public: // This sets mInfo and calls initialization functions BOOL setInfo(LLDriverParamInfo *info); + void setWearable(LLWearable *wearablep); + void setAvatar(LLVOAvatar *avatarp); + + /*virtual*/ LLViewerVisualParam * cloneParam(LLWearable* wearable) const; + // LLVisualParam Virtual functions ///*virtual*/ BOOL parseData(LLXmlTreeNode* node); /*virtual*/ void apply( ESex sex ) {} // apply is called separately for each driven param. /*virtual*/ void setWeight(F32 weight, BOOL set_by_user); /*virtual*/ void setAnimationTarget( F32 target_value, BOOL set_by_user ); /*virtual*/ void stopAnimating(BOOL set_by_user); + /*virtual*/ BOOL linkDrivenParams(visual_param_mapper mapper, bool only_cross_params); + /*virtual*/ void resetDrivenParams(); // LLViewerVisualParam Virtual functions /*virtual*/ F32 getTotalDistortion(); @@ -103,6 +114,7 @@ public: /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh); protected: F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight); + void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool set_by_user); LLVector3 mDefaultVec; // temp holder @@ -111,6 +123,7 @@ protected: LLViewerVisualParam* mCurrentDistortionParam; // Backlink only; don't make this an LLPointer. LLVOAvatar* mAvatarp; + LLWearable* mWearablep; }; #endif // LL_LLDRIVERPARAM_H diff --git a/indra/newview/lleventnotifier.cpp b/indra/newview/lleventnotifier.cpp index 80d4d21166..f6f23055ac 100644 --- a/indra/newview/lleventnotifier.cpp +++ b/indra/newview/lleventnotifier.cpp @@ -39,7 +39,6 @@ #include "llnotify.h" #include "lleventinfo.h" #include "llfloaterreg.h" -#include "llfloaterdirectory.h" #include "llfloaterworldmap.h" #include "llagent.h" @@ -197,7 +196,6 @@ bool LLEventNotification::handleResponse(const LLSD& notification, const LLSD& r break; } case 1: - gDisplayEventHack = TRUE; LLFloaterReg::showInstance("search", LLSD().insert("panel", "event").insert("id", S32(getEventID()))); break; case 2: diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp index 3976e25ba4..81d38f8f68 100644 --- a/indra/newview/llfloateravatartextures.cpp +++ b/indra/newview/llfloateravatartextures.cpp @@ -39,6 +39,7 @@ #include "lluictrlfactory.h" #include "llviewerobjectlist.h" #include "llvoavatar.h" +#include "llagentwearables.h" using namespace LLVOAvatarDefines; @@ -79,7 +80,18 @@ static void update_texture_ctrl(LLVOAvatar* avatarp, LLTextureCtrl* ctrl, ETextureIndex te) { - LLUUID id = avatarp->getTE(te)->getID(); + LLUUID id = IMG_DEFAULT_AVATAR; + EWearableType wearable_type = LLVOAvatarDictionary::getInstance()->getTEWearableType(te); + LLWearable *wearable = gAgentWearables.getWearable(wearable_type, 0); + if (wearable) + { + LLLocalTextureObject *lto = wearable->getLocalTextureObject(te); + if (lto) + { + id = lto->getID(); + } + } + //id = avatarp->getTE(te)->getID(); if (id == IMG_DEFAULT_AVATAR) { ctrl->setImageAssetID(LLUUID::null); @@ -152,7 +164,32 @@ void LLFloaterAvatarTextures::onClickDump(void* data) const LLTextureEntry* te = avatarp->getTE(i); if (!te) continue; - llinfos << "Avatar TE " << i << " id " << te->getID() << llendl; + if (LLVOAvatar::isIndexLocalTexture((ETextureIndex)i)) + { + LLUUID id = IMG_DEFAULT_AVATAR; + EWearableType wearable_type = LLVOAvatarDictionary::getInstance()->getTEWearableType((ETextureIndex)i); + LLWearable *wearable = gAgentWearables.getWearable(wearable_type, 0); + if (wearable) + { + LLLocalTextureObject *lto = wearable->getLocalTextureObject(i); + if (lto) + { + id = lto->getID(); + } + } + if (id != IMG_DEFAULT_AVATAR) + { + llinfos << "Avatar TE " << i << " id " << id << llendl; + } + else + { + llinfos << "Avatar TE " << i << " id " << "<DEFAULT>" << llendl; + } + } + else + { + llinfos << "Avatar TE " << i << " id " << te->getID() << llendl; + } } #endif } diff --git a/indra/newview/llfloaterbuycurrency.cpp b/indra/newview/llfloaterbuycurrency.cpp index e160cd01be..651122f20a 100644 --- a/indra/newview/llfloaterbuycurrency.cpp +++ b/indra/newview/llfloaterbuycurrency.cpp @@ -152,6 +152,7 @@ void LLFloaterBuyCurrencyUI::draw() { if (mManager.bought()) { + LLNotifications::instance().add("BuyLindenDollarSuccess"); closeFloater(); return; } diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp index d9cd929606..a33a605f50 100644 --- a/indra/newview/llfloaterinventory.cpp +++ b/indra/newview/llfloaterinventory.cpp @@ -1161,6 +1161,7 @@ LLUIImagePtr get_item_icon(LLAssetType::EType asset_type, 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(""); +static const LLInventoryFVBridgeBuilder INVENTORY_BRIDGE_BUILDER; LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) : LLPanel(p), @@ -1170,8 +1171,14 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) mSortOrderSetting(p.sort_order_setting), mInventory(p.inventory), mAllowMultiSelect(p.allow_multi_select), - mHasInventoryConnection(false) + mHasInventoryConnection(false), + mStartFolderString(p.start_folder) +, mBuildDefaultHierarchy(true) +, mRootInventoryItemUUID(LLUUID::null) +, mInvFVBridgeBuilder(NULL) { + mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER; + // 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)); @@ -1230,15 +1237,21 @@ BOOL LLInventoryPanel::postBuild() // build everything. mInventoryObserver = new LLInventoryPanelObserver(this); mInventory->addObserver(mInventoryObserver); - // build view of inventory if inventory ready, otherwise wait for modelChanged() callback - if (mInventory->isInventoryUsable() && !mHasInventoryConnection) + + // determine the root folder, if any, so inventory contents show just the children + // of that folder (i.e. not including the folder itself). + const LLAssetType::EType preferred_type = LLAssetType::lookupHumanReadable(mStartFolderString); + mStartFolderID = (preferred_type != LLAssetType::AT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null); + + // build view of inventory if we need default full hierarchy and inventory ready, otherwise wait for modelChanged() callback + if (mBuildDefaultHierarchy && mInventory->isInventoryUsable() && !mHasInventoryConnection) { - rebuildViewsFor(LLUUID::null, LLInventoryObserver::ADD); + rebuildViewsFor(mStartFolderID); mHasInventoryConnection = true; } // bit of a hack to make sure the inventory is open. - mFolders->openFolder(std::string("My Inventory")); + mFolders->openFolder(preferred_type != LLAssetType::AT_NONE ? LLAssetType::lookupCategoryName(preferred_type) : "My Inventory"); if (mSortOrderSetting != INHERIT_SORT_ORDER) { @@ -1271,7 +1284,7 @@ LLInventoryPanel::~LLInventoryPanel() mScroller = NULL; } - LLMemType mt(LLMemType::MTYPE_INVENTORY_FROM_XML); +LLMemType mt(LLMemType::MTYPE_INVENTORY_FROM_XML); // ! BUG ! Should this be removed? void LLInventoryPanel::draw() { // select the desired item (in case it wasn't loaded when the selection was requested) @@ -1336,7 +1349,7 @@ void LLInventoryPanel::modelChanged(U32 mask) // inventory just initialized, do complete build if ((mask & LLInventoryObserver::ADD) && gInventory.getChangedIDs().empty() && !mHasInventoryConnection) { - rebuildViewsFor(LLUUID::null, LLInventoryObserver::ADD); + rebuildViewsFor(mStartFolderID); mHasInventoryConnection = true; return; } @@ -1449,7 +1462,26 @@ void LLInventoryPanel::modelChanged(U32 mask) } } -void LLInventoryPanel::rebuildViewsFor(const LLUUID& id, U32 mask) +void LLInventoryPanel::setInvFVBridgeBuilder(const LLInventoryFVBridgeBuilder* bridge_builder) +{ + if (NULL == bridge_builder) + { + llwarns << "NULL is passed as Inventory Bridge Builder. Default will be used." << llendl; + } + else + { + mInvFVBridgeBuilder = bridge_builder; + } + + if (mInventory->isInventoryUsable() && !mHasInventoryConnection) + { + rebuildViewsFor(mRootInventoryItemUUID); + mHasInventoryConnection = true; + } +} + + +void LLInventoryPanel::rebuildViewsFor(const LLUUID& id) { LLFolderViewItem* old_view = NULL; @@ -1467,81 +1499,99 @@ 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()); + LLInventoryObject* objectp = NULL; - if (new_listener) + // Don't add the start folder (the inventory panel will show contents + // beginning with the children of the starting folder, excluding the starting folder itself). + if (id != mStartFolderID) + { + objectp = gInventory.getObject(id); + if (objectp) + { + if (objectp->getType() <= LLAssetType::AT_NONE || + objectp->getType() >= LLAssetType::AT_COUNT) { - LLFolderViewFolder::Params p; - p.name = new_listener->getDisplayName(); - p.icon = LLUI::getUIImage("Inv_FolderClosed"); - p.icon_open = LLUI::getUIImage("Inv_FolderOpen"); - p.root = mFolders; - p.listener = new_listener; - LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(p); - - folderp->setItemSortOrder(mFolders->getSortOrder()); - itemp = folderp; + llwarns << "LLInventoryPanel::buildNewViews called with objectp->mType == " + << ((S32) objectp->getType()) + << " (shouldn't happen)" << llendl; } - } - 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) + else if (objectp->getType() == LLAssetType::AT_CATEGORY && + objectp->getActualType() != LLAssetType::AT_LINK_FOLDER) { - 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); - } - } + LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(), + objectp->getType(), + LLInventoryType::IT_CATEGORY, + this, + objectp->getUUID()); - LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolders->getItemByID(objectp->getParentUUID()); - - if (itemp) - { - if (parent_folder) + 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 { - itemp->addToFolder(parent_folder, mFolders); + // Build new view for item + LLInventoryItem* item = (LLInventoryItem*)objectp; + LLInvFVBridge* new_listener = mInvFVBridgeBuilder->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); + } } - else + + if (itemp) { - llwarns << "Couldn't find parent folder for child " << itemp->getLabel() << llendl; - delete itemp; + + const LLUUID &parent_id = objectp->getParentUUID(); + LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolders->getItemByID(parent_id); + + // If this item's parent is the starting folder, then just add it to the top level (recall that + // the starting folder isn't actually represented in the view, parent_folder would be NULL in + // this case otherwise). + if (parent_id == mStartFolderID) + { + parent_folder = mFolders; + } + + 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))) + + // If this is a folder, add the children of the folder and recursively add any + // child folders. + if ((id == mStartFolderID) || + (objectp && objectp->getType() == LLAssetType::AT_CATEGORY)) { LLViewerInventoryCategory::cat_array_t* categories; LLViewerInventoryItem::item_array_t* items; @@ -1812,7 +1862,6 @@ 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()); @@ -1832,22 +1881,28 @@ bool LLInventoryPanel::attachObject(const LLSD& userdata) { return true; } - LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(id); - if(item && gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID())) + for (std::set<LLUUID>::const_iterator set_iter = selected_items.begin(); + set_iter != selected_items.end(); + ++set_iter) { - 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); + const LLUUID &id = *set_iter; + 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); diff --git a/indra/newview/llfloaterinventory.h b/indra/newview/llfloaterinventory.h index 1aaac74c87..1666f18c05 100644 --- a/indra/newview/llfloaterinventory.h +++ b/indra/newview/llfloaterinventory.h @@ -57,6 +57,7 @@ class LLFolderViewItem; class LLInventoryFilter; class LLInventoryModel; class LLInvFVBridge; +class LLInventoryFVBridgeBuilder; class LLMenuBarGL; class LLCheckBoxCtrl; class LLSpinCtrl; @@ -94,12 +95,14 @@ public: Optional<LLInventoryModel*> inventory; Optional<bool> allow_multi_select; Optional<Filter> filter; + Optional<std::string> start_folder; Params() : sort_order_setting("sort_order_setting"), inventory("", &gInventory), allow_multi_select("allow_multi_select", true), - filter("filter") + filter("filter"), + start_folder("start_folder") {} }; @@ -108,7 +111,7 @@ protected: friend class LLUICtrlFactory; public: - ~LLInventoryPanel(); + virtual ~LLInventoryPanel(); LLInventoryModel* getModel() { return mInventory; } @@ -169,17 +172,46 @@ public: 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); + void rebuildViewsFor(const LLUUID& id); + virtual void buildNewViews(const LLUUID& id); // made virtual to support derived classes. EXT-719 + + // Be sure that passed pointer will be destroyed where it was created. + void setInvFVBridgeBuilder(const LLInventoryFVBridgeBuilder* bridge_builder); protected: LLInventoryModel* mInventory; LLInventoryObserver* mInventoryObserver; - LLFolderView* mFolders; - LLScrollContainer* mScroller; BOOL mAllowMultiSelect; std::string mSortOrderSetting; + +//private: // Can not make these private - needed by llinventorysubtreepanel + LLFolderView* mFolders; + std::string mStartFolderString; + LLUUID mStartFolderID; + LLScrollContainer* mScroller; bool mHasInventoryConnection; + + /** + * Flag specified if default inventory hierarchy should be created in postBuild() + */ + bool mBuildDefaultHierarchy; + + /** + * Contains UUID of Inventory item from which hierarchy should be built. + * Should be set by derived class before modelChanged() is called. + * Default is LLUUID::null that means total Inventory hierarchy. + */ + LLUUID mRootInventoryItemUUID; + + /** + * Pointer to LLInventoryFVBridgeBuilder. + * + * It is set in LLInventoryPanel's constructor and can be overridden in derived classes with + * another implementation. + * Take into account it will not be deleted by LLInventoryPanel itself. + */ + const LLInventoryFVBridgeBuilder* mInvFVBridgeBuilder; + }; class LLFloaterInventory; diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index c1031ee437..488d71aa70 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -744,6 +744,7 @@ void LLPanelLandGeneral::refreshNames() if (!parcel) { mTextOwner->setText(LLStringUtil::null); + mTextGroup->setText(LLStringUtil::null); return; } @@ -764,6 +765,13 @@ void LLPanelLandGeneral::refreshNames() } mTextOwner->setText(owner); + std::string group; + if (!parcel->getGroupID().isNull()) + { + group = LLSLURL::buildCommand("group", parcel->getGroupID(), "inspect"); + } + mTextGroup->setText(group); + const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID(); if(auth_buyer_id.notNull()) { @@ -781,20 +789,6 @@ void LLPanelLandGeneral::refreshNames() // virtual void LLPanelLandGeneral::draw() { - LLParcel *parcel = mParcel->getParcel(); - if (parcel) - { - std::string group; - if (!parcel->getGroupID().isNull()) - { - // *TODO: Change to "inspect" when we have group inspectors and - // move into refreshNames() above - // group = LLSLURL::buildCommand("group", parcel->getGroupID(), "inspect"); - gCacheName->getGroupName(parcel->getGroupID(), group); - } - mTextGroup->setText(group); - } - LLPanel::draw(); } diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp new file mode 100644 index 0000000000..904263e2c2 --- /dev/null +++ b/indra/newview/llfloatersearch.cpp @@ -0,0 +1,91 @@ +/** + * @file llfloatersearch.cpp + * @author Martin Reddy + * @brief Search floater - uses an embedded web browser 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" +#include "llfloatersearch.h" +#include "llmediactrl.h" + + +LLFloaterSearch::LLFloaterSearch(const LLSD& key) : + LLFloater(key), + mBrowser(NULL) +{ +} + +BOOL LLFloaterSearch::postBuild() +{ + mBrowser = getChild<LLMediaCtrl>("browser"); + if (mBrowser) + { + mBrowser->addObserver(this); + mBrowser->setTrusted(true); + mBrowser->setHomePageUrl(getString("search_url")); + } + + return TRUE; +} + +void LLFloaterSearch::onOpen(const LLSD& key) +{ + search(key); +} + +void LLFloaterSearch::handleMediaEvent(LLPluginClassMedia *self, EMediaEvent event) +{ + switch (event) + { + case MEDIA_EVENT_NAVIGATE_BEGIN: + childSetText("status_text", getString("loading_text")); + break; + + case MEDIA_EVENT_NAVIGATE_COMPLETE: + childSetText("status_text", getString("done_text")); + break; + + default: + break; + } +} + +void LLFloaterSearch::search(const LLSD &key) +{ + if (mBrowser) + { + std::string query = getString("search_url"); + if (key.has("id")) + { + query += std::string("?q=") + key["id"].asString(); + } + mBrowser->navigateTo(query); + } +} diff --git a/indra/newview/llfloatersearch.h b/indra/newview/llfloatersearch.h new file mode 100644 index 0000000000..46af53b154 --- /dev/null +++ b/indra/newview/llfloatersearch.h @@ -0,0 +1,74 @@ +/** + * @file llfloatersearch.h + * @author Martin Reddy + * @brief Search floater - uses an embedded web browser 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_LLFLOATERSEARCH_H +#define LL_LLFLOATERSEARCH_H + +#include "llfloater.h" +#include "llviewermediaobserver.h" + +#include <string> + +class LLMediaCtrl; + +/// +/// The search floater allows users to perform all search operations. +/// All search functionality is now implemented via web services and +/// so this floater simply embeds a web view and displays the search +/// web page. The browser control is explicitly marked as "trusted" +/// so that the user can click on teleport links in search results. +/// +class LLFloaterSearch : + public LLFloater, + public LLViewerMediaObserver +{ +public: + LLFloaterSearch(const LLSD& key); + + /// show the search floater with a new search + /*virtual*/ void onOpen(const LLSD& key); + + /// perform a search with the specific search term + void search(const LLSD &key); + +private: + /*virtual*/ BOOL postBuild(); + + // inherited from LLViewerMediaObserver + /*virtual*/ void handleMediaEvent(LLPluginClassMedia *self, EMediaEvent event); + + LLMediaCtrl *mBrowser; +}; + +#endif // LL_LLFLOATERSEARCH_H + diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 63953580fe..92980c22c7 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -1038,12 +1038,13 @@ void LLFloaterTools::getMediaState() &&first_object->permModify() )) { - childSetEnabled("media_tex", FALSE); + childSetEnabled("Add_Media", FALSE); +/* childSetEnabled("media_tex", FALSE); childSetEnabled("add_media", FALSE); childSetEnabled("delete_media", FALSE); childSetEnabled("edit_media", FALSE); childSetEnabled("media_info", FALSE); - media_info->setEnabled(FALSE); + media_info->setEnabled(FALSE);*/ media_info->clear(); clearMediaSettings(); return; @@ -1054,13 +1055,14 @@ void LLFloaterTools::getMediaState() if(!has_media_capability) { - childSetEnabled("media_tex", FALSE); + childSetEnabled("Add_Media", FALSE); + /* childSetEnabled("media_tex", FALSE); childSetEnabled("add_media", FALSE); childSetEnabled("delete_media", FALSE); childSetEnabled("edit_media", FALSE); childSetEnabled("media_info", FALSE); media_info->setEnabled(FALSE); - media_info->clear(); + media_info->clear();*/ clearMediaSettings(); return; } @@ -1081,6 +1083,7 @@ void LLFloaterTools::getMediaState() LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, has_media ); bool bool_has_media = (has_media & LLTextureEntry::MF_HAS_MEDIA); + const LLMediaEntry default_media_data; struct functor_getter_media_data : public LLSelectedTEGetFunctor< LLMediaEntry> @@ -1108,6 +1111,7 @@ void LLFloaterTools::getMediaState() // update UI depending on whether "object" (prim or face) has media // and whether or not you are allowed to edit it. + childSetEnabled("Add_Media", editable); // IF all the faces have media (or all dont have media) if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo ) { diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 3fd0875709..155262ee13 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -190,6 +190,8 @@ LLFolderView::LLFolderView(const Params& p) mDragAndDropThisFrame(FALSE), mCallbackRegistrar(NULL), mParentPanel(p.parent_panel) +, mUseEllipses(false) +, mDraggingOverItem(NULL) { LLRect rect = p.rect; LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom); @@ -481,6 +483,11 @@ void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent) scroll_rect = mScrollContainer->getContentWindowRect(); } width = llmax(mMinWidth, scroll_rect.getWidth()); + + // restrict width with scroll container's width + if (mUseEllipses) + width = scroll_rect.getWidth(); + LLView::reshape(width, height, called_from_parent); mReshapeSignal(mSelectedItems, FALSE); @@ -1224,12 +1231,42 @@ void LLFolderView::copy() BOOL LLFolderView::canCut() const { - return FALSE; + if (!(getVisible() && getEnabled() && (mSelectedItems.size() > 0))) + { + return FALSE; + } + + for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it) + { + const LLFolderViewItem* item = *selected_it; + const LLFolderViewEventListener* listener = item->getListener(); + if (!listener || !listener->isItemMovable()) + { + return FALSE; + } + } + return TRUE; } void LLFolderView::cut() { - // implement Windows-style cut-and-leave + // clear the inventory clipboard + LLInventoryClipboard::instance().reset(); + S32 count = mSelectedItems.size(); + if(getVisible() && getEnabled() && (count > 0)) + { + LLFolderViewEventListener* listener = NULL; + selected_items_t::iterator item_it; + for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it) + { + listener = (*item_it)->getListener(); + if(listener) + { + listener->cutToClipboard(); + } + } + } + mSearchString.clear(); } BOOL LLFolderView::canPaste() const diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index 69c0c5b132..ebfb4efde2 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -104,8 +104,6 @@ public: Mandatory<LLPanel*> parent_panel; Optional<LLUUID> task_id; }; - LLFolderView( const std::string& name, LLUIImagePtr root_folder_icon, const LLRect& rect, - const LLUUID& source_id, LLPanel *parent_view ); LLFolderView(const Params&); virtual ~LLFolderView( void ); @@ -182,6 +180,9 @@ public: BOOL startDrag(LLToolDragAndDrop::ESource source); void setDragAndDropThisFrame() { mDragAndDropThisFrame = TRUE; } + void setDraggingOverItem(LLFolderViewItem* item) { mDraggingOverItem = item; } + LLFolderViewItem* getDraggingOverItem() { return mDraggingOverItem; } + // deletion functionality void removeSelectedItems(); @@ -250,6 +251,8 @@ public: void setShowSingleSelection(BOOL show); BOOL getShowSingleSelection() { return mShowSingleSelection; } F32 getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); } + void setUseEllipses(bool use_ellipses) { mUseEllipses = use_ellipses; } + bool getUseEllipses() { return mUseEllipses; } void addItemID(const LLUUID& id, LLFolderViewItem* itemp); void removeItemID(const LLUUID& id); @@ -329,6 +332,17 @@ protected: LLPanel* mParentPanel; + /** + * Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll. + * NOTE: For now it uses only to cut LLFolderViewItem::mLabel text to be used for Landmarks in Places Panel. + */ + bool mUseEllipses; // See EXT-719 + + /** + * Contains item under mouse pointer while dragging + */ + LLFolderViewItem* mDraggingOverItem; // See EXT-719 + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* mCallbackRegistrar; public: diff --git a/indra/newview/llfoldervieweventlistener.h b/indra/newview/llfoldervieweventlistener.h index 254ce4062a..ff38da279a 100644 --- a/indra/newview/llfoldervieweventlistener.h +++ b/indra/newview/llfoldervieweventlistener.h @@ -68,7 +68,7 @@ public: 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 isItemMovable( void ) const = 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; diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index 879b33e571..9208beec9e 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -36,6 +36,7 @@ // viewer includes #include "llfolderview.h" // Items depend extensively on LLFolderViews #include "llfoldervieweventlistener.h" +#include "llinventorybridge.h" // for LLItemBridge in LLInventorySort::operator() #include "llinventoryfilter.h" #include "llinventorymodel.h" // *TODO: make it take a pointer to an inventory-model interface #include "llviewercontrol.h" // gSavedSettings @@ -134,6 +135,7 @@ LLFolderViewItem::LLFolderViewItem(LLFolderViewItem::Params p) mListener(p.listener), mArrowImage(p.folder_arrow_image), mBoxImage(p.selection_image) +, mDontShowInHierarhy(false) { refresh(); } @@ -316,7 +318,12 @@ void LLFolderViewItem::arrangeFromRoot() S32 height = 0; S32 width = 0; - root->arrange( &width, &height, 0 ); + S32 total_height = root->arrange( &width, &height, 0 ); + + LLSD params; + params["action"] = "size_changes"; + params["height"] = total_height; + getParent()->notifyParent(params); } // Utility function for LLFolderView @@ -389,12 +396,22 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation) } *width = llmax(*width, mLabelWidth + mIndentation); + + // determine if we need to use ellipses to avoid horizontal scroll. EXT-719 + bool use_ellipses = getRoot()->getUseEllipses(); + if (use_ellipses) + { + // limit to set rect to avoid horizontal scrollbar + *width = llmin(*width, getRoot()->getRect().getWidth()); + } *height = getItemHeight(); return *height; } S32 LLFolderViewItem::getItemHeight() { + if (mDontShowInHierarhy) return 0; + S32 icon_height = mIcon->getHeight(); S32 label_height = llround(getLabelFontForStyle(mLabelStyle)->getLineHeight()); return llmax( icon_height, label_height ) + ICON_PAD; @@ -785,7 +802,10 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, } if(mParentFolder && !handled) { + // store this item to get it in LLFolderBridge::dragItemIntoFolder on drop event. + mRoot->setDraggingOverItem(this); handled = mParentFolder->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg); + mRoot->setDraggingOverItem(NULL); } if (handled) { @@ -798,6 +818,8 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, void LLFolderViewItem::draw() { + if (mDontShowInHierarhy) return; + 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); @@ -952,7 +974,8 @@ void LLFolderViewItem::draw() font->renderUTF8( mLabel, 0, text_left, y, color, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, - S32_MAX, S32_MAX, &right_x, FALSE ); + S32_MAX, getRect().getWidth() - (S32) text_left, &right_x, TRUE); + if (!mLabelSuffix.empty()) { font->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor, @@ -2460,6 +2483,28 @@ bool LLInventorySort::updateSort(U32 order) bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b) { + // ignore sort order for landmarks in the Favorites folder. + // they should be always sorted as in Favorites bar. See EXT-719 + if (a->getSortGroup() == SG_ITEM && b->getSortGroup() == SG_ITEM + && a->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK + && b->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK) + { + + static LLUUID favorites_folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE); + + LLUUID a_uuid = a->getParentFolder()->getListener()->getUUID(); + LLUUID b_uuid = b->getParentFolder()->getListener()->getUUID(); + + if (a_uuid == favorites_folder_id && b_uuid == favorites_folder_id) + { + // *TODO: mantipov: probably it is better to add an appropriate method to LLFolderViewItem + // or to LLInvFVBridge + S32 a_sort = (static_cast<const LLItemBridge*>(a->getListener()))->getItem()->getSortField(); + S32 b_sort = (static_cast<const LLItemBridge*>(b->getListener()))->getItem()->getSortField(); + return a_sort < b_sort; + } + } + // 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 diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h index 09c97662d9..90c346b381 100644 --- a/indra/newview/llfolderviewitem.h +++ b/indra/newview/llfolderviewitem.h @@ -158,6 +158,7 @@ protected: LLUIImagePtr mBoxImage; BOOL mIsLoading; LLTimer mTimeSinceRequestStart; + bool mDontShowInHierarhy; // helper function to change the selection from the root. void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected); @@ -200,6 +201,7 @@ public: // 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(); + void setDontShowInHierarchy(bool dont_show) { mDontShowInHierarhy = dont_show; } // applies filters to control visibility of inventory items virtual void filter( LLInventoryFilter& filter); diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index d1cbe96906..220fb3c8a0 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -35,13 +35,14 @@ #include "llgroupactions.h" +// Viewer includes #include "llagent.h" +#include "llcommandhandler.h" #include "llfloaterreg.h" #include "llgroupmgr.h" #include "llimview.h" // for gIMMgr #include "llsidetray.h" - -#include "llcommandhandler.h" +#include "llstatusbar.h" // can_afford_transaction() // // Globals @@ -96,6 +97,13 @@ public: return true; } + if (tokens[1].asString() == "inspect") + { + LLSD key; + key["group_id"] = group_id; + LLFloaterReg::showInstance("inspect_group", key); + return true; + } return false; } }; @@ -108,6 +116,52 @@ void LLGroupActions::search() } // static +void LLGroupActions::join(const LLUUID& group_id) +{ + LLGroupMgrGroupData* gdatap = + LLGroupMgr::getInstance()->getGroupData(group_id); + + if (gdatap) + { + S32 cost = gdatap->mMembershipFee; + LLSD args; + args["COST"] = llformat("%d", cost); + LLSD payload; + payload["group_id"] = group_id; + + if (can_afford_transaction(cost)) + { + LLNotifications::instance().add("JoinGroupCanAfford", args, payload, onJoinGroup); + } + else + { + LLNotifications::instance().add("JoinGroupCannotAfford", args, payload); + } + } + else + { + llwarns << "LLGroupMgr::getInstance()->getGroupData(" << group_id + << ") was NULL" << llendl; + } +} + +// static +bool LLGroupActions::onJoinGroup(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + + if (option == 1) + { + // user clicked cancel + return false; + } + + LLGroupMgr::getInstance()-> + sendGroupMemberJoin(notification["payload"]["group_id"].asUUID()); + return false; +} + +// static void LLGroupActions::leave(const LLUUID& group_id) { if (group_id.isNull()) @@ -240,6 +294,14 @@ void LLGroupActions::startChat(const LLUUID& group_id) } // static +bool LLGroupActions::isInGroup(const LLUUID& group_id) +{ + // *TODO: Move all the LLAgent group stuff into another class, such as + // this one. + return gAgent.isInGroup(group_id); +} + +// static bool LLGroupActions::isAvatarMemberOfGroup(const LLUUID& group_id, const LLUUID& avatar_id) { if(group_id.isNull() || avatar_id.isNull()) diff --git a/indra/newview/llgroupactions.h b/indra/newview/llgroupactions.h index 9fe1da8af2..74c84d1561 100644 --- a/indra/newview/llgroupactions.h +++ b/indra/newview/llgroupactions.h @@ -47,6 +47,9 @@ public: */ static void search(); + /// Join a group. Assumes LLGroupMgr has data for that group already. + static void join(const LLUUID& group_id); + /** * Invokes "Leave Group" floater. */ @@ -87,6 +90,9 @@ public: */ static void startChat(const LLUUID& group_id); + /// Returns if the current user is a member of the group + static bool isInGroup(const LLUUID& group_id); + /** * Returns true if avatar is in group. * @@ -97,6 +103,7 @@ public: static bool isAvatarMemberOfGroup(const LLUUID& group_id, const LLUUID& avatar_id); private: + static bool onJoinGroup(const LLSD& notification, const LLSD& response); static bool onLeaveGroup(const LLSD& notification, const LLSD& response); }; diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp index ae869d9ac4..27e31d4edd 100644 --- a/indra/newview/llgrouplist.cpp +++ b/indra/newview/llgrouplist.cpp @@ -315,7 +315,7 @@ void LLGroupListItem::setActive(bool active) // rebuild the text. This will cause problems if the text contains // hyperlinks, as their styles will be wrong. std::string text = mGroupNameBox->getText(); - mGroupNameBox->setText(LLStringUtil::null);// *HACK: replace with clear() when it's fixed. + mGroupNameBox->setText(LLStringUtil::null); mGroupNameBox->appendText(text, false, style_params); } diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 5e50fad008..0626a5c3d3 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -50,7 +50,6 @@ #include "llstatusbar.h" #include "lleconomy.h" #include "llviewerwindow.h" -#include "llfloaterdirectory.h" #include "llpanelgroup.h" #include "llgroupactions.h" #include "lluictrlfactory.h" @@ -1232,8 +1231,6 @@ void LLGroupMgr::processJoinGroupReply(LLMessageSystem* msg, void ** data) LLGroupMgr::getInstance()->clearGroupData(group_id); // refresh the floater for this group, if any. LLGroupActions::refresh(group_id); - // refresh the group panel of the search window, if necessary. - LLFloaterDirectory::refreshGroup(group_id); } } @@ -1254,8 +1251,6 @@ void LLGroupMgr::processLeaveGroupReply(LLMessageSystem* msg, void ** data) LLGroupMgr::getInstance()->clearGroupData(group_id); // close the floater for this group, if any. LLGroupActions::closeGroup(group_id); - // refresh the group panel of the search window, if necessary. - LLFloaterDirectory::refreshGroup(group_id); } } @@ -1325,11 +1320,16 @@ void LLGroupMgr::notifyObservers(LLGroupChange gc) { for (group_map_t::iterator gi = mGroups.begin(); gi != mGroups.end(); ++gi) { + LLUUID group_id = gi->first; if (gi->second->mChanged) { + // Copy the map because observers may remove themselves on update + observer_multimap_t observers = mObservers; + // find all observers for this group id - observer_multimap_t::iterator oi = mObservers.find(gi->first); - for (; oi != mObservers.end(); ++oi) + observer_multimap_t::iterator oi = observers.lower_bound(group_id); + observer_multimap_t::iterator end = observers.upper_bound(group_id); + for (; oi != end; ++oi) { oi->second->changed(gc); } diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index 680106c7bb..a35c04440b 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -63,13 +63,15 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id) mDialog(IM_NOTHING_SPECIAL), mHistoryEditor(NULL), mInputEditor(NULL), - mPositioned(false) + mPositioned(false), + mSessionInitialized(false) { - EInstantMessage type = LLIMModel::getInstance()->getType(session_id); - if(IM_COUNT != type) + LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(mSessionID); + if (im_session) { - mDialog = type; - + mSessionInitialized = im_session->mSessionInitialized; + + mDialog = im_session->mType; if (IM_NOTHING_SPECIAL == mDialog || IM_SESSION_P2P_INVITE == mDialog) { mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelIMControl, this); @@ -139,10 +141,16 @@ void LLIMFloater::sendMsg() 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); + if (mSessionInitialized) + { + LLIMModel::sendMessage(utf8_text, mSessionID, + mOtherParticipantUUID,mDialog); + } + else + { + //queue up the message to send once the session is initialized + mQueuedMsgsForInit.append(utf8_text); + } mInputEditor->setText(LLStringUtil::null); @@ -200,6 +208,8 @@ BOOL LLIMFloater::postBuild() LLLogChat::loadHistory(getTitle(), &chatFromLogFile, (void *)this); } + //*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla" + //see LLFloaterIMPanel for how it is done (IB) return LLDockableFloater::postBuild(); } @@ -337,6 +347,37 @@ bool LLIMFloater::toggle(const LLUUID& session_id) } } +//static +LLIMFloater* LLIMFloater::findInstance(const LLUUID& session_id) +{ + return LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id); +} + +void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id) +{ + mSessionInitialized = true; + + if (mSessionID != im_session_id) + { + mSessionID = im_session_id; + setKey(im_session_id); + } + + //*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB) + + + //need to send delayed messaged collected while waiting for session initialization + if (!mQueuedMsgsForInit.size()) return; + LLSD::array_iterator iter; + for ( iter = mQueuedMsgsForInit.beginArray(); + iter != mQueuedMsgsForInit.endArray(); + ++iter) + { + LLIMModel::sendMessage(iter->asString(), mSessionID, + mOtherParticipantUUID, mDialog); + } +} + void LLIMFloater::updateMessages() { std::list<LLSD> messages = LLIMModel::instance().getMessages(mSessionID, mLastMessageIndex+1); @@ -457,3 +498,4 @@ void LLIMFloater::chatFromLogFile(LLLogChat::ELogLineType type, std::string line self->mHistoryEditor->appendText(message, true, LLStyle::Params().color(LLUIColorTable::instance().getColor("ChatHistoryTextColor"))); self->mHistoryEditor->blockUndo(); } + diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index 5276013568..9b519ee7e3 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -68,6 +68,10 @@ public: // Returns true iff panel became visible static bool toggle(const LLUUID& session_id); + static LLIMFloater* findInstance(const LLUUID& session_id); + + void sessionInitReplyReceived(const LLUUID& im_session_id); + // get new messages from LLIMModel void updateMessages(); static void onSendMsg( LLUICtrl*, void*); @@ -108,6 +112,9 @@ private: LLViewerTextEditor* mHistoryEditor; LLLineEditor* mInputEditor; bool mPositioned; + + bool mSessionInitialized; + LLSD mQueuedMsgsForInit; }; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 4478a62ea3..619e7044b4 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -144,6 +144,8 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& // All participants will be added to the list of people we've recently interacted with. mSpeakers->addListener(&LLRecentPeople::instance(), "add"); + //we need to wait for session initialization for outgoing ad-hoc and group chat session + //correct session id for initiated ad-hoc chat will be received from the server if (!LLIMModel::getInstance()->sendStartSession(mSessionID, mOtherParticipantID, mInitialTargetIDs, mType)) { @@ -181,26 +183,44 @@ LLIMModel::LLIMSession::~LLIMSession() mVoiceChannel = NULL; } +void LLIMModel::LLIMSession::sessionInitReplyReceived(const LLUUID& new_session_id) +{ + mSessionInitialized = true; + + if (new_session_id != mSessionID) + { + mSessionID = new_session_id; + mVoiceChannel->updateSessionID(new_session_id); + } +} + LLIMModel::LLIMSession* LLIMModel::findIMSession(const LLUUID& session_id) const { return get_if_there(LLIMModel::instance().sSessionsMap, session_id, (LLIMModel::LLIMSession*) NULL); } +//*TODO change name to represent session initialization aspect (IB) void LLIMModel::updateSessionID(const LLUUID& old_session_id, const LLUUID& new_session_id) { - if (new_session_id == old_session_id) return; - LLIMSession* session = findIMSession(old_session_id); if (session) { - session->mSessionID = new_session_id; - session->mVoiceChannel->updateSessionID(new_session_id); + session->sessionInitReplyReceived(new_session_id); - session->mSessionInitialized = true; + if (old_session_id != new_session_id) + { + sSessionsMap.erase(old_session_id); + sSessionsMap[new_session_id] = session; - sSessionsMap.erase(old_session_id); - sSessionsMap[new_session_id] = session; + gIMMgr->notifyObserverSessionIDUpdated(old_session_id, new_session_id); + } + + LLIMFloater* im_floater = LLIMFloater::findInstance(old_session_id); + if (im_floater) + { + im_floater->sessionInitReplyReceived(new_session_id); + } } //*TODO remove this "floater" stuff when Communicate Floater is gone @@ -736,18 +756,10 @@ bool LLIMModel::sendStartSession( temp_session_id, other_participant_id, dialog); - - switch(dialog) - { - case IM_SESSION_GROUP_START: - gMessageSystem->addBinaryDataFast( + gMessageSystem->addBinaryDataFast( _PREHASH_BinaryBucket, EMPTY_BINARY_BUCKET, EMPTY_BINARY_BUCKET_SIZE); - break; - default: - break; - } gAgent.sendReliableMessage(); return true; @@ -789,6 +801,9 @@ bool LLIMModel::sendStartSession( other_participant_id, agents); } + + //we also need to wait for reply from the server in case of ad-hoc chat (we'll get new session id) + return true; } return false; @@ -1291,9 +1306,16 @@ void LLIMMgr::addMessage( new_session_id = computeSessionID(dialog, other_participant_id); } + //*NOTE session_name is empty in case of incoming P2P sessions + std::string fixed_session_name = from; + if(!session_name.empty() && session_name.size()>1) + { + fixed_session_name = session_name; + } + if (!LLIMModel::getInstance()->findIMSession(new_session_id)) { - LLIMModel::instance().newSession(session_id, session_name, dialog, other_participant_id); + LLIMModel::getInstance()->newSession(session_id, fixed_session_name, dialog, other_participant_id); } floater = findFloaterBySession(new_session_id); @@ -1310,17 +1332,12 @@ void LLIMMgr::addMessage( // create IM window as necessary if(!floater) { - std::string name = from; - if(!session_name.empty() && session_name.size()>1) - { - name = session_name; - } floater = createFloater( new_session_id, other_participant_id, - name, + fixed_session_name, dialog, FALSE); @@ -1869,6 +1886,15 @@ void LLIMMgr::notifyObserverSessionRemoved(const LLUUID& session_id) } } +void LLIMMgr::notifyObserverSessionIDUpdated( const LLUUID& old_session_id, const LLUUID& new_session_id ) +{ + for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++) + { + (*it)->sessionIDUpdated(old_session_id, new_session_id); + } + +} + void LLIMMgr::addSessionObserver(LLIMSessionObserver *observer) { mSessionObservers.push_back(observer); diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index df28c16bb1..84646a9a6f 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -56,6 +56,8 @@ public: const EInstantMessage& type, const LLUUID& other_participant_id, const std::vector<LLUUID>& ids); virtual ~LLIMSession(); + void sessionInitReplyReceived(const LLUUID& new_session_id); + LLUUID mSessionID; std::string mName; EInstantMessage mType; @@ -153,6 +155,7 @@ 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; + virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) = 0; }; @@ -304,6 +307,7 @@ private: void notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id); void notifyObserverSessionRemoved(const LLUUID& session_id); + void notifyObserverSessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id); private: std::set<LLHandle<LLFloater> > mFloaters; diff --git a/indra/newview/llinspect.cpp b/indra/newview/llinspect.cpp new file mode 100644 index 0000000000..aa299014ee --- /dev/null +++ b/indra/newview/llinspect.cpp @@ -0,0 +1,97 @@ +/** + * @file llinspect.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 "llinspect.h" + +#include "llcontrol.h" // LLCachedControl +#include "llui.h" // LLUI::sSettingsGroups + +LLInspect::LLInspect(const LLSD& key) +: LLFloater(key), + mCloseTimer(), + mOpenTimer() +{ +} + +LLInspect::~LLInspect() +{ +} + +// virtual +void LLInspect::draw() +{ + static LLCachedControl<F32> FADE_TIME(*LLUI::sSettingGroups["config"], "InspectorFadeTime", 1.f); + if (mOpenTimer.getStarted()) + { + F32 alpha = clamp_rescale(mOpenTimer.getElapsedTimeF32(), 0.f, FADE_TIME, 0.f, 1.f); + LLViewDrawContext context(alpha); + LLFloater::draw(); + if (alpha == 1.f) + { + mOpenTimer.stop(); + } + + } + else if (mCloseTimer.getStarted()) + { + F32 alpha = clamp_rescale(mCloseTimer.getElapsedTimeF32(), 0.f, FADE_TIME, 1.f, 0.f); + LLViewDrawContext context(alpha); + LLFloater::draw(); + if (mCloseTimer.getElapsedTimeF32() > FADE_TIME) + { + closeFloater(false); + } + } + else + { + LLFloater::draw(); + } +} + +// virtual +void LLInspect::onOpen(const LLSD& data) +{ + LLFloater::onOpen(data); + + mCloseTimer.stop(); + mOpenTimer.start(); +} + +// virtual +void LLInspect::onFocusLost() +{ + LLFloater::onFocusLost(); + + // Start closing when we lose focus + mCloseTimer.start(); + mOpenTimer.stop(); +} diff --git a/indra/newview/llinspect.h b/indra/newview/llinspect.h new file mode 100644 index 0000000000..a461c2fa16 --- /dev/null +++ b/indra/newview/llinspect.h @@ -0,0 +1,61 @@ +/** + * @file llinspect.h + * + * $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 LLINSPECT_H +#define LLINSPECT_H + +#include "llfloater.h" +#include "llframetimer.h" + +/// Base class for all inspectors (super-tooltips showing a miniature +/// properties view). +class LLInspect : public LLFloater +{ +public: + LLInspect(const LLSD& key); + virtual ~LLInspect(); + + /// Inspectors have a custom fade-in/fade-out animation + /*virtual*/ void draw(); + + /// Start open animation + /*virtual*/ void onOpen(const LLSD& avatar_id); + + /// Inspectors close themselves when they lose focus + /*virtual*/ void onFocusLost(); + +private: + LLFrameTimer mCloseTimer; + LLFrameTimer mOpenTimer; +}; + +#endif + diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index 44dd11dd86..081e55971d 100644 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -41,19 +41,21 @@ #include "llcallingcard.h" #include "llfloaterreporter.h" #include "llfloaterworldmap.h" +#include "llinspect.h" #include "llmutelist.h" #include "llpanelblockedlist.h" #include "llviewermenu.h" #include "llvoiceclient.h" // Linden libraries -#include "llcontrol.h" // LLCachedControl #include "llfloater.h" #include "llfloaterreg.h" #include "llmenubutton.h" #include "lltooltip.h" // positionViewNearMouse() #include "lluictrl.h" +#include "llavatariconctrl.h" + class LLFetchAvatarData; @@ -64,7 +66,7 @@ class LLFetchAvatarData; // 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. -class LLInspectAvatar : public LLFloater +class LLInspectAvatar : public LLInspect { friend class LLFloaterReg; @@ -75,7 +77,6 @@ public: virtual ~LLInspectAvatar(); /*virtual*/ BOOL postBuild(void); - /*virtual*/ void draw(); // Because floater is single instance, need to re-parse data on each spawn // (for example, inspector about same avatar but in different position) @@ -84,9 +85,6 @@ public: // When closing they should close their gear menu /*virtual*/ void onClose(bool app_quitting); - // Inspectors close themselves when they lose focus - /*virtual*/ void onFocusLost(); - // Update view based on information from avatar properties processor void processAvatarData(LLAvatarData* data); @@ -130,8 +128,6 @@ private: // an in-flight request for avatar properties from LLAvatarPropertiesProcessor // is represented by this object LLFetchAvatarData* mPropertiesRequest; - LLFrameTimer mCloseTimer; - LLFrameTimer mOpenTimer; }; ////////////////////////////////////////////////////////////////////////////// @@ -181,12 +177,11 @@ public: }; LLInspectAvatar::LLInspectAvatar(const LLSD& sd) -: LLFloater( LLSD() ), // single_instance, doesn't really need key +: LLInspect( LLSD() ), // single_instance, doesn't really need key mAvatarID(), // set in onOpen() mPartnerID(), mAvatarName(), - mPropertiesRequest(NULL), - mCloseTimer() + mPropertiesRequest(NULL) { mCommitCallbackRegistrar.add("InspectAvatar.ViewProfile", boost::bind(&LLInspectAvatar::onClickViewProfile, this)); mCommitCallbackRegistrar.add("InspectAvatar.AddFriend", boost::bind(&LLInspectAvatar::onClickAddFriend, this)); @@ -232,35 +227,7 @@ BOOL LLInspectAvatar::postBuild(void) return TRUE; } -void LLInspectAvatar::draw() -{ - static LLCachedControl<F32> FADE_TIME(*LLUI::sSettingGroups["config"], "InspectorFadeTime", 1.f); - if (mOpenTimer.getStarted()) - { - F32 alpha = clamp_rescale(mOpenTimer.getElapsedTimeF32(), 0.f, FADE_TIME, 0.f, 1.f); - LLViewDrawContext context(alpha); - LLFloater::draw(); - if (alpha == 1.f) - { - mOpenTimer.stop(); - } - } - else if (mCloseTimer.getStarted()) - { - F32 alpha = clamp_rescale(mCloseTimer.getElapsedTimeF32(), 0.f, FADE_TIME, 1.f, 0.f); - LLViewDrawContext context(alpha); - LLFloater::draw(); - if (mCloseTimer.getElapsedTimeF32() > FADE_TIME) - { - closeFloater(false); - } - } - else - { - LLFloater::draw(); - } -} // Multiple calls to showInstance("inspect_avatar", foo) will provide different @@ -268,8 +235,8 @@ void LLInspectAvatar::draw() //virtual void LLInspectAvatar::onOpen(const LLSD& data) { - mCloseTimer.stop(); - mOpenTimer.start(); + // Start open animation + LLInspect::onOpen(data); // Extract appropriate avatar id mAvatarID = data["avatar_id"]; @@ -304,14 +271,6 @@ void LLInspectAvatar::onClose(bool app_quitting) getChild<LLMenuButton>("gear_btn")->hideMenu(); } -//virtual -void LLInspectAvatar::onFocusLost() -{ - // Start closing when we lose focus - mCloseTimer.start(); - mOpenTimer.stop(); -} - void LLInspectAvatar::requestUpdate() { // Don't make network requests when spawning from the debug menu at the @@ -347,6 +306,10 @@ void LLInspectAvatar::requestUpdate() // and this may result in the image being visible sooner. // *NOTE: This may generate a duplicate avatar properties request, but that // will be suppressed internally in the avatar properties processor. + + //remove avatar id from cache to get fresh info + LLAvatarIconIDCache::getInstance()->remove(mAvatarID); + childSetValue("avatar_icon", LLSD(mAvatarID) ); gCacheName->get(mAvatarID, FALSE, diff --git a/indra/newview/llinspectgroup.cpp b/indra/newview/llinspectgroup.cpp new file mode 100644 index 0000000000..e079e27e56 --- /dev/null +++ b/indra/newview/llinspectgroup.cpp @@ -0,0 +1,323 @@ +/** + * @file llinspectgroup.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 "llinspectgroup.h" + +// viewer files +#include "llgroupactions.h" +#include "llgroupmgr.h" +#include "llinspect.h" + +// Linden libraries +#include "llcontrol.h" // LLCachedControl +#include "llfloater.h" +#include "llfloaterreg.h" +#include "llresmgr.h" // getMonetaryString() +#include "lltooltip.h" // positionViewNearMouse() +#include "lltrans.h" +#include "lluictrl.h" + +class LLFetchGroupData; + + +////////////////////////////////////////////////////////////////////////////// +// LLInspectGroup +////////////////////////////////////////////////////////////////////////////// + +/// Group Inspector, a small information window used when clicking +/// on group names in the 2D UI +class LLInspectGroup : public LLInspect +{ + friend class LLFloaterReg; + +public: + // key["group_id"] - Group ID for which to show information + // Inspector will be positioned relative to current mouse position + LLInspectGroup(const LLSD& key); + virtual ~LLInspectGroup(); + + // Because floater is single instance, need to re-parse data on each spawn + // (for example, inspector about same group but in different position) + /*virtual*/ void onOpen(const LLSD& group_id); + + // When closing they should close their gear menu + /*virtual*/ void onClose(bool app_quitting); + + // Update view based on information from group manager + void processGroupData(); + + // Make network requests for all the data to display in this view. + // Used on construction and if avatar id changes. + void requestUpdate(); + + // Callback for gCacheName to look up group name + // Faster than waiting for group properties to return + void nameUpdatedCallback(const LLUUID& id, + const std::string& first, + const std::string& last, + BOOL is_group); + + // Button/menu callbacks + void onClickViewProfile(); + void onClickJoin(); + void onClickLeave(); + +private: + LLUUID mGroupID; + // an in-flight network request for group properties + // is represented by this object + LLFetchGroupData* mPropertiesRequest; +}; + +////////////////////////////////////////////////////////////////////////////// +// LLFetchGroupData +////////////////////////////////////////////////////////////////////////////// + +// This object represents a pending request for avatar properties information +class LLFetchGroupData : public LLGroupMgrObserver +{ +public: + // If the inspector closes it will delete the pending request object, so the + // inspector pointer will be valid for the lifetime of this object + LLFetchGroupData(const LLUUID& group_id, LLInspectGroup* inspector) + : LLGroupMgrObserver(group_id), + mInspector(inspector) + { + LLGroupMgr* mgr = LLGroupMgr::getInstance(); + // register ourselves as an observer + mgr->addObserver(this); + // send a request + mgr->sendGroupPropertiesRequest(group_id); + } + + ~LLFetchGroupData() + { + // remove ourselves as an observer + LLGroupMgr::getInstance()->removeObserver(this); + } + + void changed(LLGroupChange gc) + { + if (gc == GC_PROPERTIES) + { + mInspector->processGroupData(); + } + } + + LLInspectGroup* mInspector; +}; + +LLInspectGroup::LLInspectGroup(const LLSD& sd) +: LLInspect( LLSD() ), // single_instance, doesn't really need key + mGroupID(), // set in onOpen() + mPropertiesRequest(NULL) +{ + mCommitCallbackRegistrar.add("InspectGroup.ViewProfile", + boost::bind(&LLInspectGroup::onClickViewProfile, this)); + mCommitCallbackRegistrar.add("InspectGroup.Join", + boost::bind(&LLInspectGroup::onClickJoin, this)); + mCommitCallbackRegistrar.add("InspectGroup.Leave", + boost::bind(&LLInspectGroup::onClickLeave, this)); + + // can't make the properties request until the widgets are constructed + // as it might return immediately, so do it in postBuild. +} + +LLInspectGroup::~LLInspectGroup() +{ + // clean up any pending requests so they don't call back into a deleted + // view + delete mPropertiesRequest; + mPropertiesRequest = NULL; +} + + +// Multiple calls to showInstance("inspect_avatar", foo) will provide different +// LLSD for foo, which we will catch here. +//virtual +void LLInspectGroup::onOpen(const LLSD& data) +{ + // start fade animation + LLInspect::onOpen(data); + + mGroupID = data["group_id"]; + + // Position the inspector relative to the mouse cursor + // Similar to how tooltips are positioned + // See LLToolTipMgr::createToolTip + if (data.has("pos")) + { + LLUI::positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger()); + } + else + { + LLUI::positionViewNearMouse(this); + } + + // can't call from constructor as widgets are not built yet + requestUpdate(); +} + +// virtual +void LLInspectGroup::onClose(bool app_quitting) +{ + // *TODO: If we add a gear menu, close it here +} + +void LLInspectGroup::requestUpdate() +{ + // Don't make network requests when spawning from the debug menu at the + // login screen (which is useful to work on the layout). + if (mGroupID.isNull()) + { + return; + } + + // Clear out old data so it doesn't flash between old and new + getChild<LLUICtrl>("group_name")->setValue(""); + getChild<LLUICtrl>("group_subtitle")->setValue(""); + getChild<LLUICtrl>("group_details")->setValue(""); + getChild<LLUICtrl>("group_cost")->setValue(""); + // Must have a visible button so the inspector can take focus + getChild<LLUICtrl>("leave_btn")->setVisible(true); + getChild<LLUICtrl>("join_btn")->setVisible(false); + + // Make a new request for properties + delete mPropertiesRequest; + mPropertiesRequest = new LLFetchGroupData(mGroupID, this); + + // Name lookup will be faster out of cache, use that + gCacheName->get(mGroupID, TRUE, + boost::bind(&LLInspectGroup::nameUpdatedCallback, + this, _1, _2, _3, _4)); +} + +void LLInspectGroup::nameUpdatedCallback( + const LLUUID& id, + const std::string& first, + const std::string& last, + BOOL is_group) +{ + if (id == mGroupID) + { + // group names are returned as a first name + childSetValue("group_name", LLSD(first) ); + } + + // Otherwise possibly a request for an older inspector, ignore it +} + +void LLInspectGroup::processGroupData() +{ + LLGroupMgrGroupData* data = + LLGroupMgr::getInstance()->getGroupData(mGroupID); + + if (data) + { + // Noun pluralization depends on language + std::string lang = LLUI::getLanguage(); + std::string members = + LLTrans::getCountString(lang, "GroupMembers", data->mMemberCount); + getChild<LLUICtrl>("group_subtitle")->setValue( LLSD(members) ); + + getChild<LLUICtrl>("group_details")->setValue( LLSD(data->mCharter) ); + + getChild<LLUICtrl>("group_icon")->setValue( LLSD(data->mInsigniaID) ); + + std::string cost; + bool is_member = LLGroupActions::isInGroup(mGroupID); + if (is_member) + { + cost = getString("YouAreMember"); + } + else if (data->mOpenEnrollment) + { + if (data->mMembershipFee == 0) + { + cost = getString("FreeToJoin"); + } + else + { + std::string amount = + LLResMgr::getInstance()->getMonetaryString( + data->mMembershipFee); + LLStringUtil::format_map_t args; + args["[AMOUNT]"] = amount; + cost = getString("CostToJoin", args); + } + } + else + { + cost = getString("PrivateGroup"); + } + getChild<LLUICtrl>("group_cost")->setValue(cost); + + getChild<LLUICtrl>("join_btn")->setVisible(!is_member); + getChild<LLUICtrl>("leave_btn")->setVisible(is_member); + + // Only enable join button if you are allowed to join + bool can_join = !is_member && data->mOpenEnrollment; + getChild<LLUICtrl>("join_btn")->setEnabled(can_join); + } + + // Delete the request object as it has been satisfied + delete mPropertiesRequest; + mPropertiesRequest = NULL; +} + +void LLInspectGroup::onClickViewProfile() +{ + closeFloater(); + LLGroupActions::show(mGroupID); +} + +void LLInspectGroup::onClickJoin() +{ + closeFloater(); + LLGroupActions::join(mGroupID); +} + +void LLInspectGroup::onClickLeave() +{ + closeFloater(); + LLGroupActions::leave(mGroupID); +} + +////////////////////////////////////////////////////////////////////////////// +// LLInspectGroupUtil +////////////////////////////////////////////////////////////////////////////// +void LLInspectGroupUtil::registerFloater() +{ + LLFloaterReg::add("inspect_group", "inspect_group.xml", + &LLFloaterReg::build<LLInspectGroup>); +} diff --git a/indra/newview/llinspectgroup.h b/indra/newview/llinspectgroup.h new file mode 100644 index 0000000000..dfd5cbcd55 --- /dev/null +++ b/indra/newview/llinspectgroup.h @@ -0,0 +1,41 @@ +/** + * @file llinspectgroup.h + * + * $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 LLINSPECTGROUP_H +#define LLINSPECTGROUP_H + +namespace LLInspectGroupUtil +{ + // Register with LLFloaterReg + void registerFloater(); +} + +#endif diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp index cdb3a10dfc..29cca14a7b 100644 --- a/indra/newview/llinspectobject.cpp +++ b/indra/newview/llinspectobject.cpp @@ -34,6 +34,7 @@ #include "llinspectobject.h" // Viewer +#include "llinspect.h" #include "llnotifications.h" // *TODO: Eliminate, add LLNotificationsUtil wrapper #include "llselectmgr.h" #include "llslurl.h" @@ -43,8 +44,6 @@ // Linden libraries #include "llbutton.h" // setLabel(), not virtual! #include "llclickaction.h" -#include "llcontrol.h" // LLCachedControl -#include "llfloater.h" #include "llfloaterreg.h" #include "llmenubutton.h" #include "llresmgr.h" // getMonetaryString @@ -56,15 +55,13 @@ class LLViewerObject; -// *TODO: Abstract out base class for LLInspectObject and LLInspectObject - ////////////////////////////////////////////////////////////////////////////// // LLInspectObject ////////////////////////////////////////////////////////////////////////////// // Object Inspector, a small information window used when clicking // in the ambient inspector widget for objects in the 3D world. -class LLInspectObject : public LLFloater +class LLInspectObject : public LLInspect { friend class LLFloaterReg; @@ -75,7 +72,6 @@ public: virtual ~LLInspectObject(); /*virtual*/ BOOL postBuild(void); - /*virtual*/ void draw(); // Because floater is single instance, need to re-parse data on each spawn // (for example, inspector about same avatar but in different position) @@ -84,9 +80,6 @@ public: // Release the selection and do other cleanup /*virtual*/ void onClose(bool app_quitting); - // Inspectors close themselves when they lose focus - /*virtual*/ void onFocusLost(); - private: // Refresh displayed data with information from selection manager void update(); @@ -113,16 +106,13 @@ private: private: LLUUID mObjectID; - LLFrameTimer mOpenTimer; - LLFrameTimer mCloseTimer; LLSafeHandle<LLObjectSelection> mObjectSelection; }; LLInspectObject::LLInspectObject(const LLSD& sd) -: LLFloater( LLSD() ), // single_instance, doesn't really need key +: LLInspect( LLSD() ), // single_instance, doesn't really need key mObjectID(), // set in onOpen() - mCloseTimer(), - mOpenTimer() + mObjectSelection() { // can't make the properties request until the widgets are constructed // as it might return immediately, so do it in postBuild. @@ -181,39 +171,14 @@ BOOL LLInspectObject::postBuild(void) return TRUE; } -void LLInspectObject::draw() -{ - static LLCachedControl<F32> FADE_OUT_TIME(*LLUI::sSettingGroups["config"], "InspectorFadeTime", 1.f); - if (mOpenTimer.getStarted()) - { - F32 alpha = clamp_rescale(mOpenTimer.getElapsedTimeF32(), 0.f, FADE_OUT_TIME, 0.f, 1.f); - LLViewDrawContext context(alpha); - LLFloater::draw(); - } - else if (mCloseTimer.getStarted()) - { - F32 alpha = clamp_rescale(mCloseTimer.getElapsedTimeF32(), 0.f, FADE_OUT_TIME, 1.f, 0.f); - LLViewDrawContext context(alpha); - LLFloater::draw(); - if (mCloseTimer.getElapsedTimeF32() > FADE_OUT_TIME) - { - closeFloater(false); - } - } - else - { - LLFloater::draw(); - } -} - // Multiple calls to showInstance("inspect_avatar", foo) will provide different // LLSD for foo, which we will catch here. //virtual void LLInspectObject::onOpen(const LLSD& data) { - mCloseTimer.stop(); - mOpenTimer.start(); + // Start animation + LLInspect::onOpen(data); // Extract appropriate avatar id mObjectID = data["object_id"]; @@ -260,14 +225,6 @@ void LLInspectObject::onClose(bool app_quitting) getChild<LLMenuButton>("gear_btn")->hideMenu(); } -//virtual -void LLInspectObject::onFocusLost() -{ - // Start closing when we lose focus - mCloseTimer.start(); - mOpenTimer.stop(); -} - void LLInspectObject::update() { diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 1880a574a7..db7d4f4c8f 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -257,11 +257,22 @@ void LLInvFVBridge::renameLinkedItems(const LLUUID &item_id, const std::string& } // Can be moved to another folder -BOOL LLInvFVBridge::isItemMovable() +BOOL LLInvFVBridge::isItemMovable() const { return TRUE; } +/*virtual*/ +/** + * @brief Adds this item into clipboard storage + */ +void LLInvFVBridge::cutToClipboard() +{ + if(isItemMovable()) + { + LLInventoryClipboard::instance().cut(mUUID); + } +} // *TODO: make sure this does the right thing void LLInvFVBridge::showProperties() { @@ -487,6 +498,11 @@ BOOL LLInvFVBridge::isClipboardPasteableAsLink() const return FALSE; } } + const LLViewerInventoryCategory *cat = model->getCategory(objects.get(i)); + if (cat && !LLAssetType::lookupCanLink(cat->getPreferredType())) + { + return FALSE; + } } return TRUE; } @@ -907,6 +923,24 @@ void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid) } // +=================================================+ +// | InventoryFVBridgeBuilder | +// +=================================================+ +LLInvFVBridge* LLInventoryFVBridgeBuilder::createBridge(LLAssetType::EType asset_type, + LLAssetType::EType actual_asset_type, + LLInventoryType::EType inv_type, + LLInventoryPanel* inventory, + const LLUUID& uuid, + U32 flags /* = 0x00 */) const +{ + return LLInvFVBridge::createBridge(asset_type, + actual_asset_type, + inv_type, + inventory, + uuid, + flags); +} + +// +=================================================+ // | LLItemBridge | // +=================================================+ @@ -1316,7 +1350,7 @@ BOOL LLItemBridge::isItemPermissive() const LLFolderBridge* LLFolderBridge::sSelf=NULL; // Can be moved to another folder -BOOL LLFolderBridge::isItemMovable() +BOOL LLFolderBridge::isItemMovable() const { LLInventoryObject* obj = getInventoryObject(); if(obj) @@ -1581,6 +1615,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, // if target is an outfit or current outfit folder we use link if (move_is_into_current_outfit || move_is_into_outfit) { +#if SUPPORT_ENSEMBLES // BAP - should skip if dup. if (move_is_into_current_outfit) { @@ -1597,6 +1632,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, LLAssetType::AT_LINK_FOLDER, cb); } +#endif } else { @@ -1978,6 +2014,7 @@ void LLFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model modifyOutfit(FALSE); return; } +#if SUPPORT_ENSEMBLES else if ("wearasensemble" == action) { LLInventoryModel* model = getInventoryModel(); @@ -1987,6 +2024,7 @@ void LLFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model LLAppearanceManager::wearEnsemble(cat,true); return; } +#endif else if ("addtooutfit" == action) { modifyOutfit(TRUE); @@ -2175,19 +2213,28 @@ void LLFolderBridge::pasteFromClipboard() LLDynamicArray<LLUUID> objects; LLInventoryClipboard::instance().retrieve(objects); S32 count = objects.count(); - LLUUID parent_id(mUUID); + const LLUUID parent_id(mUUID); 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)); + if(LLInventoryClipboard::instance().isCutMode()) + { + // move_inventory_item() is not enough, + //we have to update inventory locally too + changeItemParent(model, dynamic_cast<LLViewerInventoryItem*>(item), parent_id, FALSE); + } + else + { + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + parent_id, + std::string(), + LLPointer<LLInventoryCallback>(NULL)); + } } } } @@ -2205,6 +2252,7 @@ void LLFolderBridge::pasteLinkFromClipboard() for(S32 i = 0; i < count; i++) { const LLUUID &object_id = objects.get(i); +#if SUPPORT_ENSEMBLES if (LLInventoryCategory *cat = model->getCategory(object_id)) { link_inventory_item( @@ -2215,7 +2263,9 @@ void LLFolderBridge::pasteLinkFromClipboard() LLAssetType::AT_LINK_FOLDER, LLPointer<LLInventoryCallback>(NULL)); } - else if (LLInventoryItem *item = model->getItem(object_id)) + else +#endif + if (LLInventoryItem *item = model->getItem(object_id)) { link_inventory_item( gAgent.getID(), @@ -2656,6 +2706,56 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response return false; } +/* +Next functions intended to reorder items in the inventory folder and save order on server +Is now used for Favorites folder. + +*TODO: refactoring is needed with Favorites Bar functionality. Probably should be moved in LLInventoryModel +*/ +void saveItemsOrder(LLInventoryModel::item_array_t& items) +{ + int sortField = 0; + + // current order is saved by setting incremental values (1, 2, 3, ...) for the sort field + for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i) + { + LLViewerInventoryItem* item = *i; + + item->setSortField(++sortField); + item->setComplete(TRUE); + item->updateServer(FALSE); + + gInventory.updateItem(item); + } + + gInventory.notifyObservers(); +} + +LLInventoryModel::item_array_t::iterator findItemByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id) +{ + LLInventoryModel::item_array_t::iterator result = items.end(); + + for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i) + { + if ((*i)->getUUID() == id) + { + result = i; + break; + } + } + + return result; +} + +void updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& srcItemId, const LLUUID& destItemId) +{ + LLViewerInventoryItem* srcItem = gInventory.getItem(srcItemId); + LLViewerInventoryItem* destItem = gInventory.getItem(destItemId); + + items.erase(findItemByUUID(items, srcItem->getUUID())); + items.insert(findItemByUUID(items, destItem->getUUID()), srcItem); +} + BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop) { @@ -2714,7 +2814,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, } } - accept = is_movable && (mUUID != inv_item->getParentUUID()); + LLUUID favorites_id = model->findCategoryUUIDForType(LLAssetType::AT_FAVORITE); + + // we can move item inside a folder only if this folder is Favorites. See EXT-719 + accept = is_movable && ((mUUID != inv_item->getParentUUID()) || (mUUID == favorites_id)); if(accept && drop) { if (inv_item->getType() == LLAssetType::AT_GESTURE @@ -2736,8 +2839,28 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, } } - LLUUID favorites_id = model->findCategoryUUIDForType(LLAssetType::AT_FAVORITE); - if (favorites_id == mUUID) // if target is the favorites folder we use copy + // if dragging from/into favorites folder only reorder items + if ((mUUID == inv_item->getParentUUID()) && (favorites_id == mUUID)) + { + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + LLIsType is_type(LLAssetType::AT_LANDMARK); + model->collectDescendentsIf(favorites_id, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type); + + LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); + LLFolderViewItem* itemp = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL; + if (itemp) + { + LLUUID srcItemId = inv_item->getUUID(); + LLUUID destItemId = itemp->getListener()->getUUID(); + + // update order + updateItemsOrder(items, srcItemId, destItemId); + + saveItemsOrder(items); + } + } + else if (favorites_id == mUUID) // if target is the favorites folder we use copy { copy_inventory_item( gAgent.getID(), @@ -3011,14 +3134,14 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } items.push_back(std::string("Landmark Separator")); - items.push_back(std::string("Teleport To Landmark")); + items.push_back(std::string("About Landmark")); // Disable "About Landmark" menu item for // multiple landmarks selected. Only one landmark // info panel can be shown at a time. if ((flags & FIRST_SELECTED_ITEM) == 0) { - disabled_items.push_back(std::string("Teleport To Landmark")); + disabled_items.push_back(std::string("About Landmark")); } hideContextEntries(menu, items, disabled_items); @@ -3725,11 +3848,13 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach payload["attachment_point"] = attach_pt; - if (attachment && attachment->getObject()) +#if !ENABLE_MULTIATTACHMENTS + if (attachment && attachment->getNumObjects() > 0) { LLNotifications::instance().add("ReplaceAttachment", LLSD(), payload, confirm_replace_attachment_rez); } else +#endif { LLNotifications::instance().forceResponse(LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/); } @@ -3737,6 +3862,16 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& response) { + LLVOAvatar *avatarp = gAgent.getAvatarObject(); + + if (!avatarp->canAttachMoreObjects()) + { + LLSD args; + args["MAX_ATTACHMENTS"] = llformat("%d", MAX_AGENT_ATTACHMENTS); + LLNotifications::instance().add("MaxAttachmentsOnOutfit", args); + return false; + } + S32 option = LLNotification::getSelectedOption(notification, response); if (option == 0/*YES*/) { @@ -3752,7 +3887,11 @@ bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& respon msg->nextBlockFast(_PREHASH_ObjectData); msg->addUUIDFast(_PREHASH_ItemID, itemp->getUUID()); msg->addUUIDFast(_PREHASH_OwnerID, itemp->getPermissions().getOwner()); - msg->addU8Fast(_PREHASH_AttachmentPt, notification["payload"]["attachment_point"].asInteger()); + U8 attachment_pt = notification["payload"]["attachment_point"].asInteger(); +#if ENABLE_MULTIATTACHMENTS + attachment_pt |= ATTACHMENT_ADD; +#endif + msg->addU8Fast(_PREHASH_AttachmentPt, attachment_pt); pack_permissions_slam(msg, itemp->getFlags(), itemp->getPermissions()); msg->addStringFast(_PREHASH_Name, itemp->getName()); msg->addStringFast(_PREHASH_Description, itemp->getDescription()); @@ -3813,6 +3952,12 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) // commented out for DEV-32347 //items.push_back(std::string("Restore to Last Position")); + if (!avatarp->canAttachMoreObjects()) + { + disabled_items.push_back(std::string("Object Wear")); + disabled_items.push_back(std::string("Attach To")); + disabled_items.push_back(std::string("Attach To HUD")); + } LLMenuGL* attach_menu = menu.findChildMenuByName("Attach To", TRUE); LLMenuGL* attach_hud_menu = menu.findChildMenuByName("Attach To HUD", TRUE); LLVOAvatar *avatarp = gAgent.getAvatarObject(); diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index bc950520aa..d1d2c57f07 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -120,6 +120,11 @@ protected: LLInventoryPanel* mIP; }; +const std::string safe_inv_type_lookup(LLInventoryType::EType inv_type); +void hideContextEntries(LLMenuGL& menu, + const std::vector<std::string> &entries_to_show, + const std::vector<std::string> &disabled_entries); + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLInvFVBridge (& it's derived classes) // @@ -168,13 +173,13 @@ public: virtual BOOL isItemRenameable() const { return TRUE; } //virtual BOOL renameItem(const std::string& new_name) {} virtual BOOL isItemRemovable(); - virtual BOOL isItemMovable(); + virtual BOOL isItemMovable() const; //virtual BOOL removeItem() = 0; virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch); virtual void move(LLFolderViewEventListener* new_parent_bridge) {} virtual BOOL isItemCopyable() const { return FALSE; } virtual BOOL copyToClipboard() const { return FALSE; } - virtual void cutToClipboard() {} + virtual void cutToClipboard(); virtual BOOL isClipboardPasteable() const; virtual BOOL isClipboardPasteableAsLink() const; virtual void pasteFromClipboard() {} @@ -221,6 +226,22 @@ protected: void purgeItem(LLInventoryModel *model, const LLUUID &uuid); }; +/** + * This class intended to build Folder View Bridge via LLInvFVBridge::createBridge. + * It can be overridden with another way of creation necessary Inventory-Folder-View-Bridge. + */ +class LLInventoryFVBridgeBuilder +{ +public: + virtual ~LLInventoryFVBridgeBuilder(){} + virtual LLInvFVBridge* createBridge(LLAssetType::EType asset_type, + LLAssetType::EType actual_asset_type, + LLInventoryType::EType inv_type, + LLInventoryPanel* inventory, + const LLUUID& uuid, + U32 flags = 0x00) const; +}; + class LLItemBridge : public LLInvFVBridge { @@ -291,7 +312,7 @@ public: void* cargo_data); virtual BOOL isItemRemovable(); - virtual BOOL isItemMovable(); + virtual BOOL isItemMovable() const ; virtual BOOL isUpToDate() const; virtual BOOL isItemCopyable() const; virtual BOOL isClipboardPasteableAsLink() const; diff --git a/indra/newview/llinventoryclipboard.cpp b/indra/newview/llinventoryclipboard.cpp index 94ffcbd457..71a5e12332 100644 --- a/indra/newview/llinventoryclipboard.cpp +++ b/indra/newview/llinventoryclipboard.cpp @@ -47,6 +47,7 @@ LLInventoryClipboard LLInventoryClipboard::sInstance; ///---------------------------------------------------------------------------- LLInventoryClipboard::LLInventoryClipboard() +: mCutMode(false) { } @@ -77,6 +78,16 @@ void LLInventoryClipboard::store(const LLDynamicArray<LLUUID>& inv_objects) } } +void LLInventoryClipboard::cut(const LLUUID& object) +{ + if(!mCutMode && !mObjects.empty()) + { + //looks like there are some stored items, reset clipboard state + reset(); + } + mCutMode = true; + add(object); +} void LLInventoryClipboard::retrieve(LLDynamicArray<LLUUID>& inv_objects) const { inv_objects.reset(); @@ -90,6 +101,7 @@ void LLInventoryClipboard::retrieve(LLDynamicArray<LLUUID>& inv_objects) const void LLInventoryClipboard::reset() { mObjects.reset(); + mCutMode = false; } // returns true if the clipboard has something pasteable in it. diff --git a/indra/newview/llinventoryclipboard.h b/indra/newview/llinventoryclipboard.h index 7a2cf15d62..7e221d650c 100644 --- a/indra/newview/llinventoryclipboard.h +++ b/indra/newview/llinventoryclipboard.h @@ -60,6 +60,7 @@ public: // this method stores an array of objects void store(const LLDynamicArray<LLUUID>& inventory_objects); + void cut(const LLUUID& object); // this method gets the objects in the clipboard by copying them // into the array provided. void retrieve(LLDynamicArray<LLUUID>& inventory_objects) const; @@ -69,11 +70,13 @@ public: // returns true if the clipboard has something pasteable in it. BOOL hasContents() const; + bool isCutMode() const { return mCutMode; } protected: static LLInventoryClipboard sInstance; LLDynamicArray<LLUUID> mObjects; + bool mCutMode; public: // please don't actually call these diff --git a/indra/newview/lllandmarkactions.cpp b/indra/newview/lllandmarkactions.cpp index 7c759e22a8..2e6615dd91 100644 --- a/indra/newview/lllandmarkactions.cpp +++ b/indra/newview/lllandmarkactions.cpp @@ -42,16 +42,18 @@ #include "llnotifications.h" #include "llagent.h" +#include "llagentui.h" #include "llinventorymodel.h" #include "lllandmarklist.h" #include "llslurl.h" +#include "llstring.h" #include "llviewerinventory.h" #include "llviewerparcelmgr.h" +#include "llviewerwindow.h" +#include "llwindow.h" #include "llworldmap.h" -#include "lllandmark.h" -#include "llinventorymodel.h" -#include "llagentui.h" +void copy_slurl_to_clipboard_callback(const std::string& slurl); class LLFetchlLandmarkByPos : public LLInventoryCollectFunctor { @@ -303,15 +305,39 @@ void LLLandmarkActions::onRegionResponse(slurl_callback_t cb, bool LLLandmarkActions::getLandmarkGlobalPos(const LLUUID& landmarkInventoryItemID, LLVector3d& posGlobal) { + LLLandmark* landmark = LLLandmarkActions::getLandmark(landmarkInventoryItemID); + + if (NULL == landmark) + return false; + + return landmark->getGlobalPos(posGlobal); +} + +LLLandmark* LLLandmarkActions::getLandmark(const LLUUID& landmarkInventoryItemID) +{ LLViewerInventoryItem* item = gInventory.getItem(landmarkInventoryItemID); if (NULL == item) return false; const LLUUID& asset_id = item->getAssetUUID(); - LLLandmark* landmark = gLandmarkList.getAsset(asset_id, NULL); + return gLandmarkList.getAsset(asset_id, NULL); +} - if (NULL == landmark) - return false; +void LLLandmarkActions::copySLURLtoClipboard(const LLUUID& landmarkInventoryItemID) +{ + LLLandmark* landmark = LLLandmarkActions::getLandmark(landmarkInventoryItemID); + if(landmark) + { + LLVector3d global_pos; + landmark->getGlobalPos(global_pos); + LLLandmarkActions::getSLURLfromPosGlobal(global_pos,©_slurl_to_clipboard_callback,true); + } +} - return landmark->getGlobalPos(posGlobal); +void copy_slurl_to_clipboard_callback(const std::string& slurl) +{ + gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(slurl)); + LLSD args; + args["SLURL"] = slurl; + LLNotifications::instance().add("CopySLURL", args); } diff --git a/indra/newview/lllandmarkactions.h b/indra/newview/lllandmarkactions.h index ab8cc4d6a5..e882db0a92 100644 --- a/indra/newview/lllandmarkactions.h +++ b/indra/newview/lllandmarkactions.h @@ -35,6 +35,7 @@ #include "llinventorymodel.h" +class LLLandmark; /** * @brief Provides helper functions to manage landmarks */ @@ -101,6 +102,20 @@ public: // *TODO: mantipov: profide callback for cases, when Landmark is not loaded yet. static bool getLandmarkGlobalPos(const LLUUID& landmarkInventoryItemID, LLVector3d& posGlobal); + /** + * @brief Retrieve a landmark from gLandmarkList by inventory item's id + * + * @return pointer to loaded landmark from gLandmarkList or NULL if landmark does not exist. + */ + static LLLandmark* getLandmark(const LLUUID& landmarkInventoryItemID); + + /** + * @brief Performs standard action of copying of SLURL from landmark to user's clipboard. + * This action requires additional server request. The user will be notified by info message, + * when URL is copied . + */ + static void copySLURLtoClipboard(const LLUUID& landmarkInventoryItemID); + private: LLLandmarkActions(); LLLandmarkActions(const LLLandmarkActions&); diff --git a/indra/newview/lllocaltextureobject.cpp b/indra/newview/lllocaltextureobject.cpp index e4a20aea68..99c98ec16e 100644 --- a/indra/newview/lllocaltextureobject.cpp +++ b/indra/newview/lllocaltextureobject.cpp @@ -37,6 +37,7 @@ #include "llviewertexture.h" #include "lltextureentry.h" #include "lluuid.h" +#include "llwearable.h" LLLocalTextureObject::LLLocalTextureObject() : @@ -46,31 +47,33 @@ LLLocalTextureObject::LLLocalTextureObject() : mImage = NULL; } -LLLocalTextureObject::LLLocalTextureObject(LLViewerFetchedTexture *image, LLTextureEntry *entry, LLTexLayer *layer, LLUUID id) +LLLocalTextureObject::LLLocalTextureObject(LLViewerFetchedTexture *image, 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; + gGL.getTexUnit(0)->bind(mImage); mID = id; } LLLocalTextureObject::LLLocalTextureObject(const LLLocalTextureObject <o) : mImage(lto.mImage), -mTexEntry(lto.mTexEntry), -mTexLayer(lto.mTexLayer), mID(lto.mID), mIsBakedReady(lto.mIsBakedReady), mDiscard(lto.mDiscard) { + U32 num_layers = lto.getNumTexLayers(); + mTexLayers.reserve(num_layers); + for (U32 index = 0; index < num_layers; index++) + { + LLTexLayer* original_layer = lto.getTexLayer(index); + if (!original_layer) + { + llerrs << "could not clone Local Texture Object: unable to extract texlayer!" << llendl; + } + + LLTexLayer* new_layer = new LLTexLayer(*original_layer); + new_layer->setLTO(this); + mTexLayers.push_back(new_layer); + } } LLLocalTextureObject::~LLLocalTextureObject() @@ -82,14 +85,33 @@ LLViewerFetchedTexture* LLLocalTextureObject::getImage() const return mImage; } -LLTextureEntry* LLLocalTextureObject::getTexEntry() const +LLTexLayer* LLLocalTextureObject::getTexLayer(U32 index) const { - return mTexEntry.get(); + if (index >= getNumTexLayers()) + { + return NULL; + } + + return mTexLayers[index]; } -LLTexLayer* LLLocalTextureObject::getTexLayer() const +LLTexLayer* LLLocalTextureObject::getTexLayer(const std::string &name) { - return mTexLayer.get(); + for( tex_layer_p::iterator iter = mTexLayers.begin(); iter != mTexLayers.end(); iter++) + { + LLTexLayer *layer = *iter; + if (layer->getName().compare(name) == 0) + { + return layer; + } + } + + return NULL; +} + +U32 LLLocalTextureObject::getNumTexLayers() const +{ + return mTexLayers.size(); } LLUUID LLLocalTextureObject::getID() const @@ -112,24 +134,68 @@ void LLLocalTextureObject::setImage(LLViewerFetchedTexture* new_image) mImage = new_image; } -void LLLocalTextureObject::setTexEntry(LLTextureEntry *new_te) +BOOL LLLocalTextureObject::setTexLayer(LLTexLayer *new_tex_layer, U32 index) { - LLTextureEntry *ptr = NULL; - if (new_te) + if (index >= getNumTexLayers() ) + { + return FALSE; + } + + if (new_tex_layer == NULL) { - ptr = new LLTextureEntry(*new_te); + return removeTexLayer(index); } - mTexEntry = boost::shared_ptr<LLTextureEntry>(ptr); + + LLTexLayer *layer = new LLTexLayer(*new_tex_layer); + layer->setLTO(this); + + if (mTexLayers[index]) + { + delete mTexLayers[index]; + } + mTexLayers[index] = layer; + + return TRUE; +} + +BOOL LLLocalTextureObject::addTexLayer(LLTexLayer *new_tex_layer, LLWearable *wearable) +{ + if (new_tex_layer == NULL) + { + return FALSE; + } + + LLTexLayer *layer = new LLTexLayer(*new_tex_layer, wearable); + layer->setLTO(this); + mTexLayers.push_back(layer); + return TRUE; } -void LLLocalTextureObject::setTexLayer(LLTexLayer *new_tex_layer) +BOOL LLLocalTextureObject::addTexLayer(LLTexLayerTemplate *new_tex_layer, LLWearable *wearable) { - LLTexLayer *ptr = NULL; - if (new_tex_layer) + if (new_tex_layer == NULL) { - ptr = new LLTexLayer(*new_tex_layer); + return FALSE; } - mTexLayer = boost::shared_ptr<LLTexLayer>(ptr); + + LLTexLayer *layer = new LLTexLayer(*new_tex_layer, this, wearable); + layer->setLTO(this); + mTexLayers.push_back(layer); + return TRUE; +} + +BOOL LLLocalTextureObject::removeTexLayer(U32 index) +{ + if (index >= getNumTexLayers()) + { + return FALSE; + } + tex_layer_p::iterator iter = mTexLayers.begin(); + iter += index; + + delete *iter; + mTexLayers.erase(iter); + return TRUE; } void LLLocalTextureObject::setID(LLUUID new_id) diff --git a/indra/newview/lllocaltextureobject.h b/indra/newview/lllocaltextureobject.h index 79e1562dce..138bbad677 100644 --- a/indra/newview/lllocaltextureobject.h +++ b/indra/newview/lllocaltextureobject.h @@ -39,6 +39,8 @@ class LLViewerFetchedTexture; class LLUUID; class LLTexLayer; class LLTextureEntry; +class LLTexLayerTemplate; +class LLWearable; // Stores all relevant information for a single texture // assumed to have ownership of all objects referred to - @@ -47,20 +49,24 @@ class LLLocalTextureObject { public: LLLocalTextureObject(); - LLLocalTextureObject(LLViewerFetchedTexture *image, LLTextureEntry *entry, LLTexLayer *layer, LLUUID id); + LLLocalTextureObject(LLViewerFetchedTexture *image, LLUUID id); LLLocalTextureObject(const LLLocalTextureObject <o); ~LLLocalTextureObject(); LLViewerFetchedTexture* getImage() const; - LLTextureEntry* getTexEntry() const; - LLTexLayer* getTexLayer() const; + LLTexLayer* getTexLayer(U32 index) const; + LLTexLayer* getTexLayer(const std::string &name); + U32 getNumTexLayers() 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); + BOOL setTexLayer(LLTexLayer *new_tex_layer, U32 index); + BOOL addTexLayer(LLTexLayer *new_tex_layer, LLWearable *wearable); + BOOL addTexLayer(LLTexLayerTemplate *new_tex_layer, LLWearable *wearable); + BOOL removeTexLayer(U32 index); + void setID(LLUUID new_id); void setDiscard(S32 new_discard); void setBakedReady(BOOL ready); @@ -73,8 +79,9 @@ private: // 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; + typedef std::vector<LLTexLayer*> tex_layer_p; + tex_layer_p mTexLayers; + LLUUID mID; BOOL mIsBakedReady; diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp index f797f15865..6ae42d23d3 100644..100755 --- a/indra/newview/llmediadataclient.cpp +++ b/indra/newview/llmediadataclient.cpp @@ -250,7 +250,7 @@ void LLMediaDataClient::Responder::error(U32 status, const std::string& reason) /*virtual*/ void LLMediaDataClient::Responder::result(const LLSD& content) { - LL_INFOS("LLMediaDataClient") << *mRequest << "result : " << ll_pretty_print_sd(content) << LL_ENDL; + LL_INFOS("LLMediaDataClient") << *mRequest << "result : " << ll_print_sd(content) << LL_ENDL; } @@ -524,7 +524,7 @@ void LLObjectMediaDataClient::updateMedia(LLMediaDataClientObject *object) } sd_payload[LLTextureEntry::OBJECT_MEDIA_DATA_KEY] = object_media_data; - LL_INFOS("LLMediaDataClient") << "update media data: " << object->getID() << " " << ll_pretty_print_sd(sd_payload) << LL_ENDL; + LL_INFOS("LLMediaDataClient") << "update media data: " << object->getID() << " " << ll_print_sd(sd_payload) << LL_ENDL; request(object, sd_payload); } @@ -536,7 +536,7 @@ void LLObjectMediaDataClient::Responder::result(const LLSD& content) llassert(type == LLMediaDataClient::Request::GET || type == LLMediaDataClient::Request::UPDATE) if (type == LLMediaDataClient::Request::GET) { - LL_INFOS("LLMediaDataClient") << *(getRequest()) << "GET returned: " << ll_pretty_print_sd(content) << LL_ENDL; + LL_INFOS("LLMediaDataClient") << *(getRequest()) << "GET returned: " << ll_print_sd(content) << LL_ENDL; // Look for an error if (content.has("error")) @@ -614,7 +614,7 @@ void LLObjectMediaNavigateClient::Responder::error(U32 status, const std::string /*virtual*/ void LLObjectMediaNavigateClient::Responder::result(const LLSD& content) { - LL_DEBUGS("LLMediaDataClient") << *(getRequest()) << " NAVIGATE returned " << ll_pretty_print_sd(content) << LL_ENDL; + LL_INFOS("LLMediaDataClient") << *(getRequest()) << " NAVIGATE returned " << ll_print_sd(content) << LL_ENDL; if (content.has("error")) { diff --git a/indra/newview/llmediadataclient.h b/indra/newview/llmediadataclient.h index 9d0aa0981e..9d0aa0981e 100644..100755 --- a/indra/newview/llmediadataclient.h +++ b/indra/newview/llmediadataclient.h diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp index c969a7e3bb..28ddaa61c4 100644 --- a/indra/newview/llmenucommands.cpp +++ b/indra/newview/llmenucommands.cpp @@ -47,7 +47,6 @@ #include "llviewercontrol.h" #include "llfirstuse.h" #include "llfloaterchat.h" -#include "llfloaterdirectory.h" #include "llfloaterworldmap.h" #include "lllineeditor.h" #include "llnotify.h" diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 91862112a0..7160cce5cb 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -48,11 +48,9 @@ #include "llnearbychathandler.h" #include "llchannelmanager.h" -//for LLViewerTextEditor support #include "llagent.h" // gAgent #include "llfloaterscriptdebug.h" -#include "llslurl.h" -#include "llviewertexteditor.h" +#include "llchathistory.h" #include "llstylemap.h" #include "lldraghandle.h" @@ -64,7 +62,7 @@ LLNearbyChat::LLNearbyChat(const LLSD& key) : LLFloater(key), mEChatTearofState(CHAT_PINNED), mChatCaptionPanel(NULL), - mChatHistoryEditor(NULL) + mChatHistory(NULL) { m_isDirty = false; } @@ -110,7 +108,7 @@ BOOL LLNearbyChat::postBuild() gSavedSettings.declareS32("nearbychat_showicons_and_names",2,"NearByChat header settings",true); mChatCaptionPanel = getChild<LLPanel>("chat_caption", false); - mChatHistoryEditor = getChild<LLViewerTextEditor>("Chat History Editor"); + mChatHistory = getChild<LLChatHistory>("chat_history"); reshape(getRect().getWidth(), getRect().getHeight(), FALSE); @@ -185,44 +183,6 @@ LLColor4 nearbychat_get_text_color(const LLChat& chat) void LLNearbyChat::add_timestamped_line(const LLChat& chat, const LLColor4& color) { - std::string line = chat.mText; - - //chat.mText starts with Avatar Name if entered message was "/me <action>". - // In this case output chat message should be "<Avatar Name> <action>". See EXT-656 - // See also process_chat_from_simulator() in the llviewermessage.cpp where ircstyle = TRUE; - if (CHAT_STYLE_IRC != chat.mChatStyle) - line = chat.mFromName + ": " + line; - - bool prepend_newline = true; - if (gSavedSettings.getBOOL("ChatShowTimestamps")) - { - mChatHistoryEditor->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. - - std::string str_URL = chat.mURL; - - if (chat.mSourceType == CHAT_SOURCE_AGENT && - chat.mFromID != LLUUID::null) - { - str_URL = LLSLURL::buildCommand("agent", chat.mFromID, "inspect"); - } - - // If the chat line has an associated url, link it up to the name. - if (!str_URL.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); - mChatHistoryEditor->appendText(start_line, prepend_newline, - LLStyleMap::instance().lookup(chat.mFromID,str_URL)); - mChatHistoryEditor->blockUndo(); - prepend_newline = false; - } - S32 font_size = gSavedSettings.getS32("ChatFontSize"); const LLFontGL* fontp = NULL; @@ -240,8 +200,14 @@ void LLNearbyChat::add_timestamped_line(const LLChat& chat, const LLColor4& colo break; } - mChatHistoryEditor->appendText(line, prepend_newline, LLStyle::Params().color(color).font(fontp)); - mChatHistoryEditor->blockUndo(); + LLStyle::Params style_params; + style_params.color(color); + style_params.font(fontp); + LLUUID uuid = chat.mFromID; + std::string from = chat.mFromName; + std::string time = ""; + std::string message = chat.mText; + mChatHistory->appendWidgetMessage(uuid, from, time, message, style_params); } void LLNearbyChat::addMessage(const LLChat& chat) @@ -315,7 +281,7 @@ void LLNearbyChat::reshape(S32 width, S32 height, BOOL called_from_parent) mResizeBar[LLResizeBar::RIGHT]->setRect(resize_rect); } - // *NOTE: we must check mChatCaptionPanel and mChatHistoryEditor against NULL because reshape is called from the + // *NOTE: we must check mChatCaptionPanel and mChatHistory 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) @@ -326,12 +292,12 @@ void LLNearbyChat::reshape(S32 width, S32 height, BOOL called_from_parent) mChatCaptionPanel->setRect(caption_rect); } - if (NULL != mChatHistoryEditor) + if (NULL != mChatHistory) { - LLRect scroll_rect = mChatHistoryEditor->getRect(); + LLRect scroll_rect = mChatHistory->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); + mChatHistory->reshape( width - 4, height - caption_rect.getHeight() - RESIZE_BAR_THICKNESS*2, 1); + mChatHistory->setRect(scroll_rect); } // diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h index 7c8ffa3b94..47cae8ed0d 100644 --- a/indra/newview/llnearbychat.h +++ b/indra/newview/llnearbychat.h @@ -38,7 +38,7 @@ #include "llchat.h" class LLResizeBar; -class LLViewerTextEditor; +class LLChatHistory; class LLNearbyChat: public LLFloater { @@ -89,7 +89,7 @@ private: LLHandle<LLView> mPopupMenuHandle; LLPanel* mChatCaptionPanel; - LLViewerTextEditor* mChatHistoryEditor; + LLChatHistory* mChatHistory; bool m_isDirty; }; diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp index 5186a93569..c08f92b983 100644 --- a/indra/newview/llnotificationtiphandler.cpp +++ b/indra/newview/llnotificationtiphandler.cpp @@ -33,6 +33,8 @@ #include "llviewerprecompiledheaders.h" // must be first include +#include "llfloaterreg.h" +#include "llnearbychat.h" #include "llnotificationhandler.h" #include "lltoastnotifypanel.h" #include "llviewercontrol.h" @@ -96,6 +98,14 @@ bool LLTipHandler::processNotification(const LLSD& notify) LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel); if(channel) channel->addToast(p); + + // archive message in nearby chat + LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD()); + if(nearby_chat) + { + LLChat chat_msg(notification->getMessage()); + nearby_chat->addMessage(chat_msg); + } } else if (notify["sigtype"].asString() == "delete") { diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 3a3ea1fc3c..7670a5120c 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -43,6 +43,7 @@ #include "lltexturectrl.h" #include "lltooldraganddrop.h" #include "llscrollcontainer.h" +#include "llavatariconctrl.h" #include "llweb.h" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -447,6 +448,10 @@ void LLPanelAvatarProfile::processGroupProperties(const LLAvatarGroups* avatar_g void LLPanelAvatarProfile::fillCommonData(const LLAvatarData* avatar_data) { + //remove avatar id from cache to get fresh info + LLAvatarIconIDCache::getInstance()->remove(avatar_data->avatar_id); + + childSetValue("register_date", avatar_data->born_on ); childSetValue("sl_description_edit", avatar_data->about_text); childSetValue("fl_description_edit",avatar_data->fl_about_text); diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 7eaee92778..a29c9752e6 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -909,13 +909,7 @@ bool LLPanelClassified::confirmPublish(const LLSD& notification, const LLSD& res // Big hack - assume that top picks are always in a browser, // and non-finder-classifieds are always in a tab container. - if (mInFinder) - { - // TODO: enable this - //LLPanelDirClassifieds* panel = (LLPanelDirClassifieds*)getParent(); - //panel->renameClassified(mClassifiedID, mNameEditor->getText()); - } - else + if (! mInFinder) { LLTabContainer* tab = (LLTabContainer*)getParent(); tab->setCurrentTabName(mNameEditor->getText()); diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp new file mode 100644 index 0000000000..c2c32527fb --- /dev/null +++ b/indra/newview/llpaneleditwearable.cpp @@ -0,0 +1,658 @@ +/** + * @file llpaneleditwearable.cpp + * @brief UI panel for editing of a particular wearable item. + * + * $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 "llpaneleditwearable.h" +#include "llpanel.h" +#include "llwearable.h" +#include "lluictrl.h" +#include "llscrollingpanellist.h" +#include "llvisualparam.h" +#include "lltoolmorph.h" +#include "llviewerjointmesh.h" +#include "lltrans.h" +#include "llbutton.h" +#include "llsliderctrl.h" +#include "llagent.h" +#include "llvoavatarself.h" +#include "lltexteditor.h" +#include "lltextbox.h" +#include "llaccordionctrltab.h" +#include "llagentwearables.h" +#include "llscrollingpanelparam.h" + +// register panel with appropriate XML +static LLRegisterPanelClassWrapper<LLPanelEditWearable> t_edit_wearable("panel_edit_wearable"); + +// subparts of the UI for focus, camera position, etc. +enum ESubpart { + SUBPART_SHAPE_HEAD = 1, // avoid 0 + SUBPART_SHAPE_EYES, + SUBPART_SHAPE_EARS, + SUBPART_SHAPE_NOSE, + SUBPART_SHAPE_MOUTH, + SUBPART_SHAPE_CHIN, + SUBPART_SHAPE_TORSO, + SUBPART_SHAPE_LEGS, + SUBPART_SHAPE_WHOLE, + SUBPART_SHAPE_DETAIL, + SUBPART_SKIN_COLOR, + SUBPART_SKIN_FACEDETAIL, + SUBPART_SKIN_MAKEUP, + SUBPART_SKIN_BODYDETAIL, + SUBPART_HAIR_COLOR, + SUBPART_HAIR_STYLE, + SUBPART_HAIR_EYEBROWS, + SUBPART_HAIR_FACIAL, + SUBPART_EYES, + SUBPART_SHIRT, + SUBPART_PANTS, + SUBPART_SHOES, + SUBPART_SOCKS, + SUBPART_JACKET, + SUBPART_GLOVES, + SUBPART_UNDERSHIRT, + SUBPART_UNDERPANTS, + SUBPART_SKIRT, + SUBPART_ALPHA, + SUBPART_TATTOO + }; + +typedef std::vector<ESubpart> subpart_vec_t; + +// Locally defined classes + +class LLEditWearableDictionary : public LLSingleton<LLEditWearableDictionary> +{ + //-------------------------------------------------------------------- + // Constructors and Destructors + //-------------------------------------------------------------------- +public: + LLEditWearableDictionary(); + virtual ~LLEditWearableDictionary(); + + //-------------------------------------------------------------------- + // Wearable Types + //-------------------------------------------------------------------- +public: + struct WearableEntry : public LLDictionaryEntry + { + WearableEntry(EWearableType type, + const std::string &title, + const std::string &desc_title, + U8 num_subparts, ... ); // number of subparts followed by a list of ESubparts + + + const EWearableType mWearableType; + const std::string mTitle; + const std::string mDescTitle; + subpart_vec_t mSubparts; + + }; + + struct Wearables : public LLDictionary<EWearableType, WearableEntry> + { + Wearables(); + } mWearables; + + const WearableEntry* getWearable(EWearableType type) const { return mWearables.lookup(type); } + + //-------------------------------------------------------------------- + // Subparts + //-------------------------------------------------------------------- +public: + struct SubpartEntry : public LLDictionaryEntry + { + SubpartEntry(ESubpart part, + const std::string &joint, + const std::string &edit_group, + const std::string ¶m_list, + const std::string &accordion_tab, + const LLVector3d &target_offset, + const LLVector3d &camera_offset, + const ESex &sex); + + ESubpart mSubpart; + std::string mTargetJoint; + std::string mEditGroup; + std::string mParamList; + std::string mAccordionTab; + LLVector3d mTargetOffset; + LLVector3d mCameraOffset; + ESex mSex; + }; + + struct Subparts : public LLDictionary<ESubpart, SubpartEntry> + { + Subparts(); + } mSubparts; + + const SubpartEntry* getSubpart(ESubpart subpart) const { return mSubparts.lookup(subpart); } +}; + +LLEditWearableDictionary::LLEditWearableDictionary() +{ + +} + +//virtual +LLEditWearableDictionary::~LLEditWearableDictionary() +{ +} + +LLEditWearableDictionary::Wearables::Wearables() +{ + addEntry(WT_SHAPE, new WearableEntry(WT_SHAPE,"edit_shape_title","shape_desc_text",9, SUBPART_SHAPE_HEAD, SUBPART_SHAPE_EYES, SUBPART_SHAPE_EARS, SUBPART_SHAPE_NOSE, SUBPART_SHAPE_MOUTH, SUBPART_SHAPE_CHIN, SUBPART_SHAPE_TORSO, SUBPART_SHAPE_LEGS, SUBPART_SHAPE_WHOLE)); + addEntry(WT_SKIN, new WearableEntry(WT_SKIN,"edit_skin_title","skin_desc_text",4, SUBPART_SKIN_COLOR, SUBPART_SKIN_FACEDETAIL, SUBPART_SKIN_MAKEUP, SUBPART_SKIN_BODYDETAIL)); + addEntry(WT_HAIR, new WearableEntry(WT_HAIR,"edit_hair_title","hair_desc_text",4, SUBPART_HAIR_COLOR, SUBPART_HAIR_STYLE, SUBPART_HAIR_EYEBROWS, SUBPART_HAIR_FACIAL)); + addEntry(WT_EYES, new WearableEntry(WT_EYES,"edit_eyes_title","eyes_desc_text",1, SUBPART_EYES)); + addEntry(WT_SHIRT, new WearableEntry(WT_SHIRT,"edit_shirt_title","shirt_desc_text",1, SUBPART_SHIRT)); + addEntry(WT_PANTS, new WearableEntry(WT_PANTS,"edit_pants_title","pants_desc_text",1, SUBPART_PANTS)); + addEntry(WT_SHOES, new WearableEntry(WT_SHOES,"edit_shoes_title","shoes_desc_text",1, SUBPART_SHOES)); + addEntry(WT_SOCKS, new WearableEntry(WT_SOCKS,"edit_socks_title","socks_desc_text",1, SUBPART_SOCKS)); + addEntry(WT_JACKET, new WearableEntry(WT_JACKET,"edit_jacket_title","jacket_desc_text",1, SUBPART_JACKET)); + addEntry(WT_GLOVES, new WearableEntry(WT_GLOVES,"edit_gloves_title","gloves_desc_text",1, SUBPART_GLOVES)); + addEntry(WT_UNDERSHIRT, new WearableEntry(WT_UNDERSHIRT,"edit_undershirt_title","undershirt_desc_text",1, SUBPART_UNDERSHIRT)); + addEntry(WT_UNDERPANTS, new WearableEntry(WT_UNDERPANTS,"edit_underpants_title","underpants_desc_text",1, SUBPART_UNDERPANTS)); + addEntry(WT_SKIRT, new WearableEntry(WT_SKIRT,"edit_skirt_title","skirt_desc_text",1, SUBPART_SKIRT)); + addEntry(WT_ALPHA, new WearableEntry(WT_ALPHA,"edit_alpha_title","alpha_desc_text",1, SUBPART_ALPHA)); + addEntry(WT_TATTOO, new WearableEntry(WT_TATTOO,"edit_tattoo_title","tattoo_desc_text",1, SUBPART_TATTOO)); +} + +LLEditWearableDictionary::WearableEntry::WearableEntry(EWearableType type, + const std::string &title, + const std::string &desc_title, + U8 num_subparts, ... ) : + LLDictionaryEntry(title), + mWearableType(type), + mTitle(title), + mDescTitle(desc_title) +{ + va_list argp; + va_start(argp, num_subparts); + + for (U8 i = 0; i < num_subparts; ++i) + { + ESubpart part = (ESubpart)va_arg(argp,int); + mSubparts.push_back(part); + } +} + +LLEditWearableDictionary::Subparts::Subparts() +{ + addEntry(SUBPART_SHAPE_WHOLE, new SubpartEntry(SUBPART_SHAPE_WHOLE, "mPelvis", "shape_body","shape_body_param_list", "shape_body_tab", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-2.5f, 0.5f, 0.8f),SEX_BOTH)); + addEntry(SUBPART_SHAPE_HEAD, new SubpartEntry(SUBPART_SHAPE_HEAD, "mHead", "shape_head", "shape_head_param_list", "shape_head_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH)); + addEntry(SUBPART_SHAPE_EYES, new SubpartEntry(SUBPART_SHAPE_EYES, "mHead", "shape_eyes", "shape_eyes_param_list", "shape_eyes_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH)); + addEntry(SUBPART_SHAPE_EARS, new SubpartEntry(SUBPART_SHAPE_EARS, "mHead", "shape_ears", "shape_ears_param_list", "shape_ears_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH)); + addEntry(SUBPART_SHAPE_NOSE, new SubpartEntry(SUBPART_SHAPE_NOSE, "mHead", "shape_nose", "shape_nose_param_list", "shape_nose_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH)); + addEntry(SUBPART_SHAPE_MOUTH, new SubpartEntry(SUBPART_SHAPE_MOUTH, "mHead", "shape_mouth", "shape_mouth_param_list", "shape_mouth_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH)); + addEntry(SUBPART_SHAPE_CHIN, new SubpartEntry(SUBPART_SHAPE_CHIN, "mHead", "shape_chin", "shape_chin_param_list", "shape_chin_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH)); + addEntry(SUBPART_SHAPE_TORSO, new SubpartEntry(SUBPART_SHAPE_TORSO, "mTorso", "shape_torso", "shape_torso_param_list", "shape_torso_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(-1.f, 0.15f, 0.3f),SEX_BOTH)); + addEntry(SUBPART_SHAPE_LEGS, new SubpartEntry(SUBPART_SHAPE_LEGS, "mPelvis", "shape_legs", "shape_legs_param_list", "shape_legs_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH)); + + addEntry(SUBPART_SKIN_COLOR, new SubpartEntry(SUBPART_SKIN_COLOR, "mHead", "skin_color", "skin_color_param_list", "skin_color_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH)); + addEntry(SUBPART_SKIN_FACEDETAIL, new SubpartEntry(SUBPART_SKIN_FACEDETAIL, "mHead", "skin_facedetail", "skin_face_param_list", "skin_face_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH)); + addEntry(SUBPART_SKIN_MAKEUP, new SubpartEntry(SUBPART_SKIN_MAKEUP, "mHead", "skin_makeup", "skin_makeup_param_list", "skin_makeup_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH)); + addEntry(SUBPART_SKIN_BODYDETAIL, new SubpartEntry(SUBPART_SKIN_BODYDETAIL, "mPelvis", "skin_bodydetail", "skin_body_param_list", "skin_body_tab", LLVector3d(0.f, 0.f, -0.2f), LLVector3d(-2.5f, 0.5f, 0.5f),SEX_BOTH)); + + addEntry(SUBPART_HAIR_COLOR, new SubpartEntry(SUBPART_HAIR_COLOR, "mHead", "hair_color", "hair_color_param_list", "hair_color_tab", LLVector3d(0.f, 0.f, 0.10f), LLVector3d(-0.4f, 0.05f, 0.10f),SEX_BOTH)); + addEntry(SUBPART_HAIR_STYLE, new SubpartEntry(SUBPART_HAIR_STYLE, "mHead", "hair_style", "hair_style_param_list", "hair_style_tab", LLVector3d(0.f, 0.f, 0.10f), LLVector3d(-0.4f, 0.05f, 0.10f),SEX_BOTH)); + addEntry(SUBPART_HAIR_EYEBROWS, new SubpartEntry(SUBPART_HAIR_EYEBROWS, "mHead", "hair_eyebrows", "hair_eyebrows_param_list", "hair_eyebrows_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH)); + addEntry(SUBPART_HAIR_FACIAL, new SubpartEntry(SUBPART_HAIR_FACIAL, "mHead", "hair_facial", "hair_facial_param_list", "hair_facial_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_MALE)); + + addEntry(SUBPART_EYES, new SubpartEntry(SUBPART_EYES, "mHead", "eyes", "eyes_main_param_list", "eyes_main_tab", LLVector3d(0.f, 0.f, 0.05f), LLVector3d(-0.5f, 0.05f, 0.07f),SEX_BOTH)); + + addEntry(SUBPART_SHIRT, new SubpartEntry(SUBPART_SHIRT, "mTorso", "shirt", "shirt_main_param_list", "shirt_main_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(-1.f, 0.15f, 0.3f),SEX_BOTH)); + addEntry(SUBPART_PANTS, new SubpartEntry(SUBPART_PANTS, "mPelvis", "pants", "pants_main_param_list", "pants_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH)); + addEntry(SUBPART_SHOES, new SubpartEntry(SUBPART_SHOES, "mPelvis", "shoes", "shoes_main_param_list", "shoes_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH)); + addEntry(SUBPART_SOCKS, new SubpartEntry(SUBPART_SOCKS, "mPelvis", "socks", "socks_main_param_list", "socks_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH)); + addEntry(SUBPART_JACKET, new SubpartEntry(SUBPART_JACKET, "mTorso", "jacket", "jacket_main_param_list", "jacket_main_tab", LLVector3d(0.f, 0.f, 0.f), LLVector3d(-2.f, 0.1f, 0.3f),SEX_BOTH)); + addEntry(SUBPART_SKIRT, new SubpartEntry(SUBPART_SKIRT, "mPelvis", "skirt", "skirt_main_param_list", "skirt_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH)); + addEntry(SUBPART_GLOVES, new SubpartEntry(SUBPART_GLOVES, "mTorso", "gloves", "gloves_main_param_list", "gloves_main_tab", LLVector3d(0.f, 0.f, 0.f), LLVector3d(-1.f, 0.15f, 0.f),SEX_BOTH)); + addEntry(SUBPART_UNDERSHIRT, new SubpartEntry(SUBPART_UNDERSHIRT, "mTorso", "undershirt", "undershirt_main_param_list", "undershirt_main_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(-1.f, 0.15f, 0.3f),SEX_BOTH)); + addEntry(SUBPART_UNDERPANTS, new SubpartEntry(SUBPART_UNDERPANTS, "mPelvis", "underpants", "underpants_main_param_list", "underpants_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH)); + addEntry(SUBPART_ALPHA, new SubpartEntry(SUBPART_ALPHA, "mPelvis", "alpha", "alpha_main_param_list", "alpha_main_tab", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-2.5f, 0.5f, 0.8f),SEX_BOTH)); + addEntry(SUBPART_TATTOO, new SubpartEntry(SUBPART_TATTOO, "mPelvis", "tattoo", "tattoo_main_param_list", "tattoo_main_tab", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-2.5f, 0.5f, 0.8f),SEX_BOTH)); +} + +LLEditWearableDictionary::SubpartEntry::SubpartEntry(ESubpart part, + const std::string &joint, + const std::string &edit_group, + const std::string ¶m_list, + const std::string &accordion_tab, + const LLVector3d &target_offset, + const LLVector3d &camera_offset, + const ESex &sex) : + LLDictionaryEntry(edit_group), + mSubpart(part), + mTargetJoint(joint), + mEditGroup(edit_group), + mParamList(param_list), + mAccordionTab(accordion_tab), + mTargetOffset(target_offset), + mCameraOffset(camera_offset), + mSex(sex) +{ +} + + +// LLPanelEditWearable + +LLPanelEditWearable::LLPanelEditWearable() + : LLPanel() +{ +} + +//virtual +LLPanelEditWearable::~LLPanelEditWearable() +{ + +} + +// virtual +BOOL LLPanelEditWearable::postBuild() +{ + // buttons + mBtnRevert = getChild<LLButton>("revert_button"); + mBtnRevert->setClickedCallback(boost::bind(&LLPanelEditWearable::onRevertButtonClicked, this)); + + mBtnBack = getChild<LLButton>("back_btn"); + // handled at appearance panel level? + //mBtnBack->setClickedCallback(boost::bind(&LLPanelEditWearable::onBackButtonClicked, this)); + + mTextEditor = getChild<LLTextEditor>("description"); + + mPanelTitle = getChild<LLTextBox>("edit_wearable_title"); + mDescTitle = getChild<LLTextBox>("description_text"); + + // The following panels will be shown/hidden based on what wearable we're editing + // body parts + mPanelShape = getChild<LLPanel>("edit_shape_panel"); + mPanelSkin = getChild<LLPanel>("edit_skin_panel"); + mPanelEyes = getChild<LLPanel>("edit_eyes_panel"); + mPanelHair = getChild<LLPanel>("edit_hair_panel"); + + //clothes + mPanelShirt = getChild<LLPanel>("edit_shirt_panel"); + mPanelPants = getChild<LLPanel>("edit_pants_panel"); + mPanelShoes = getChild<LLPanel>("edit_shoes_panel"); + mPanelSocks = getChild<LLPanel>("edit_socks_panel"); + mPanelJacket = getChild<LLPanel>("edit_jacket_panel"); + mPanelGloves = getChild<LLPanel>("edit_gloves_panel"); + mPanelUndershirt = getChild<LLPanel>("edit_undershirt_panel"); + mPanelUnderpants = getChild<LLPanel>("edit_underpants_panel"); + mPanelSkirt = getChild<LLPanel>("edit_skirt_panel"); + mPanelAlpha = getChild<LLPanel>("edit_alpha_panel"); + mPanelTattoo = getChild<LLPanel>("edit_tattoo_panel"); + + mWearablePtr = NULL; + + return TRUE; +} + +// virtual +// LLUICtrl +BOOL LLPanelEditWearable::isDirty() const +{ + BOOL isDirty = FALSE; + if (mWearablePtr) + { + if (mWearablePtr->isDirty() || + mWearablePtr->getName().compare(mTextEditor->getText()) != 0) + { + isDirty = TRUE; + } + } + return isDirty; +} +//virtual +void LLPanelEditWearable::draw() +{ + BOOL is_dirty = isDirty(); + mBtnRevert->setEnabled(is_dirty); + + LLPanel::draw(); +} + +void LLPanelEditWearable::setWearable(LLWearable *wearable) +{ + showWearable(mWearablePtr, FALSE); + mWearablePtr = wearable; + showWearable(mWearablePtr, TRUE); + + initializePanel(); +} + +//static +void LLPanelEditWearable::onRevertButtonClicked(void* userdata) +{ + LLPanelEditWearable *panel = (LLPanelEditWearable*) userdata; + panel->revertChanges(); +} + + +void LLPanelEditWearable::saveChanges() +{ + if (!mWearablePtr || !isDirty()) + { + // do nothing if no unsaved changes + return; + } + + U32 index = gAgentWearables.getWearableIndex(mWearablePtr->getType(), mWearablePtr); + + if (mWearablePtr->getName().compare(mTextEditor->getText()) != 0) + { + // the name of the wearable has changed, re-save wearable with new name + gAgentWearables.saveWearableAs(mWearablePtr->getType(), index, mTextEditor->getText(), FALSE); + } + else + { + gAgentWearables.saveWearable(mWearablePtr->getType(), index); + } +} + +void LLPanelEditWearable::revertChanges() +{ + if (!mWearablePtr || !isDirty()) + { + // no unsaved changes to revert + return; + } + + mWearablePtr->revertValues(); + mTextEditor->setText(mWearablePtr->getName()); +} + +void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show) +{ + if (!wearable) + { + return; + } + + EWearableType type = wearable->getType(); + LLPanel *targetPanel = NULL; + std::string title; + std::string description_title; + + const LLEditWearableDictionary::WearableEntry *entry = LLEditWearableDictionary::getInstance()->getWearable(type); + if (!entry) + { + llwarns << "called LLPanelEditWearable::showWearable with an invalid wearable type! (" << type << ")" << llendl; + return; + } + + targetPanel = getPanel(type); + title = getString(entry->mTitle); + description_title = getString(entry->mDescTitle); + + targetPanel->setVisible(show); + if (show) + { + mPanelTitle->setText(title); + mDescTitle->setText(description_title); + } + +} + +void LLPanelEditWearable::initializePanel() +{ + if (!mWearablePtr) + { + // cannot initialize with a null reference. + return; + } + + EWearableType type = mWearablePtr->getType(); + + // set name + mTextEditor->setText(mWearablePtr->getName()); + + // clear and rebuild visual param list + const LLEditWearableDictionary::WearableEntry *wearable_entry = LLEditWearableDictionary::getInstance()->getWearable(type); + if (!wearable_entry) + { + llwarns << "could not get wearable dictionary entry for wearable of type: " << type << llendl; + return; + } + U8 num_subparts = wearable_entry->mSubparts.size(); + + for (U8 index = 0; index < num_subparts; ++index) + { + // dive into data structures to get the panel we need + ESubpart subpart_e = wearable_entry->mSubparts[index]; + const LLEditWearableDictionary::SubpartEntry *subpart_entry = LLEditWearableDictionary::getInstance()->getSubpart(subpart_e); + + if (!subpart_entry) + { + llwarns << "could not get wearable subpart dictionary entry for subpart: " << subpart_e << llendl; + continue; + } + + const std::string scrolling_panel = subpart_entry->mParamList; + const std::string accordion_tab = subpart_entry->mAccordionTab; + + LLScrollingPanelList *panel_list = getChild<LLScrollingPanelList>(scrolling_panel); + LLAccordionCtrlTab *tab = getChild<LLAccordionCtrlTab>(accordion_tab); + + if (!panel_list) + { + llwarns << "could not get scrolling panel list: " << scrolling_panel << llendl; + continue; + } + + if (!tab) + { + llwarns << "could not get llaccordionctrltab from UI with name: " << accordion_tab << llendl; + continue; + } + + // what edit group do we want to extract params for? + const std::string edit_group = subpart_entry->mEditGroup; + + // storage for ordered list of visual params + value_map_t sorted_params; + getSortedParams(sorted_params, edit_group); + + buildParamList(panel_list, sorted_params, tab); + + updateScrollingPanelUI(); + } + +} + +void LLPanelEditWearable::updateScrollingPanelUI() +{ + // do nothing if we don't have a valid wearable we're editing + if (mWearablePtr == NULL) + { + return; + } + + EWearableType type = mWearablePtr->getType(); + LLPanel *panel = getPanel(type); + + if(panel && (mWearablePtr->getItemID().notNull())) + { + const LLEditWearableDictionary::WearableEntry *wearable_entry = LLEditWearableDictionary::getInstance()->getWearable(type); + U8 num_subparts = wearable_entry->mSubparts.size(); + + LLScrollingPanelParam::sUpdateDelayFrames = 0; + for (U8 index = 0; index < num_subparts; ++index) + { + // dive into data structures to get the panel we need + ESubpart subpart_e = wearable_entry->mSubparts[index]; + const LLEditWearableDictionary::SubpartEntry *subpart_entry = LLEditWearableDictionary::getInstance()->getSubpart(subpart_e); + + const std::string scrolling_panel = subpart_entry->mParamList; + + LLScrollingPanelList *panel_list = getChild<LLScrollingPanelList>(scrolling_panel); + + if (!panel_list) + { + llwarns << "could not get scrolling panel list: " << scrolling_panel << llendl; + continue; + } + + panel_list->updatePanels(TRUE); + } + } +} + +LLPanel* LLPanelEditWearable::getPanel(EWearableType type) +{ + switch (type) + { + case WT_SHAPE: + return mPanelShape; + break; + + case WT_SKIN: + return mPanelSkin; + break; + + case WT_HAIR: + return mPanelHair; + break; + + case WT_EYES: + return mPanelEyes; + break; + + case WT_SHIRT: + return mPanelShirt; + break; + + case WT_PANTS: + return mPanelPants; + break; + + case WT_SHOES: + return mPanelShoes; + break; + + case WT_SOCKS: + return mPanelSocks; + break; + + case WT_JACKET: + return mPanelJacket; + break; + + case WT_GLOVES: + return mPanelGloves; + break; + + case WT_UNDERSHIRT: + return mPanelUndershirt; + break; + + case WT_UNDERPANTS: + return mPanelUnderpants; + break; + + case WT_SKIRT: + return mPanelSkirt; + break; + + case WT_ALPHA: + return mPanelAlpha; + break; + + case WT_TATTOO: + return mPanelTattoo; + break; + default: + break; + } + return NULL; +} + +void LLPanelEditWearable::getSortedParams(value_map_t &sorted_params, const std::string &edit_group) +{ + LLWearable::visualParamCluster_t param_list; + ESex avatar_sex = gAgent.getAvatarObject()->getSex(); + + mWearablePtr->getVisualParams(param_list); + + LLWearable::visualParamCluster_t::iterator iter = param_list.begin(); + LLWearable::visualParamCluster_t::iterator end = param_list.end(); + + for (; iter != end; ++iter) + { + LLViewerVisualParam *param = (LLViewerVisualParam*) *iter; + + if (param->getID() == -1 + || param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE + || param->getEditGroup() != edit_group + || !(param->getSex() & avatar_sex)) + { + continue; + } + + value_map_t::value_type vt(-param->getDisplayOrder(), param); + llassert( sorted_params.find(-param->getDisplayOrder()) == sorted_params.end() ); //check for duplicates + sorted_params.insert(vt); + } +} + +void LLPanelEditWearable::buildParamList(LLScrollingPanelList *panel_list, value_map_t &sorted_params, LLAccordionCtrlTab *tab) +{ + // sorted_params is sorted according to magnitude of effect from + // least to greatest. Adding to the front of the child list + // reverses that order. + if( panel_list ) + { + panel_list->clearPanels(); + value_map_t::iterator end = sorted_params.end(); + S32 height = 0; + for(value_map_t::iterator it = sorted_params.begin(); it != end; ++it) + { + LLPanel::Params p; + p.name("LLScrollingPanelParam"); + p.rect(LLRect(0, LLScrollingPanelParam::PARAM_PANEL_HEIGHT, LLScrollingPanelParam::PARAM_PANEL_WIDTH, 0 )); + LLScrollingPanelParam* panel_param = new LLScrollingPanelParam( p, NULL, (*it).second, TRUE, this->getWearable()); + height = panel_list->addPanel( panel_param ); + } + + S32 width = tab->getRect().getWidth(); + + tab->reshape(width,height + tab->getHeaderHeight()+10,FALSE); + } +} + + + + + diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h new file mode 100644 index 0000000000..4178659617 --- /dev/null +++ b/indra/newview/llpaneleditwearable.h @@ -0,0 +1,114 @@ +/** + * @file llfloatercustomize.h + * @brief The customize avatar floater, triggered by "Appearance..." + * + * $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_LLPANELEDITWEARABLE_H +#define LL_LLPANELEDITWEARABLE_H + +#include "llpanel.h" +#include "llscrollingpanellist.h" +#include "llmodaldialog.h" +#include "llwearabledictionary.h" + +class LLWearable; +class LLTextEditor; +class LLTextBox; +class LLViewerVisualParam; +class LLVisualParamHint; +class LLViewerJointMesh; +class LLAccordionCtrlTab; + +class LLPanelEditWearable : public LLPanel +{ +public: + LLPanelEditWearable( ); + virtual ~LLPanelEditWearable(); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ BOOL isDirty() const; // LLUICtrl + /*virtual*/ void draw(); + + LLWearable* getWearable() { return mWearablePtr; } + void setWearable(LLWearable *wearable); + + void saveChanges(); + void revertChanges(); + + static void onRevertButtonClicked(void* userdata); + +private: + typedef std::map<F32, LLViewerVisualParam*> value_map_t; + + void showWearable(LLWearable* wearable, BOOL show); + void initializePanel(); + void updateScrollingPanelUI(); + LLPanel* getPanel(EWearableType type); + void getSortedParams(value_map_t &sorted_params, const std::string &edit_group); + void buildParamList(LLScrollingPanelList *panel_list, value_map_t &sorted_params, LLAccordionCtrlTab *tab); + + // the pointer to the wearable we're editing. NULL means we're not editing a wearable. + LLWearable *mWearablePtr; + + // these are constant no matter what wearable we're editing + LLButton *mBtnRevert; + LLButton *mBtnBack; + + LLTextBox *mPanelTitle; + LLTextBox *mDescTitle; + + + // This text editor reference will change each time we edit a new wearable - + // it will be grabbed from the currently visible panel + LLTextEditor *mTextEditor; + + // The following panels will be shown/hidden based on what wearable we're editing + // body parts + LLPanel *mPanelShape; + LLPanel *mPanelSkin; + LLPanel *mPanelEyes; + LLPanel *mPanelHair; + + //clothes + LLPanel *mPanelShirt; + LLPanel *mPanelPants; + LLPanel *mPanelShoes; + LLPanel *mPanelSocks; + LLPanel *mPanelJacket; + LLPanel *mPanelGloves; + LLPanel *mPanelUndershirt; + LLPanel *mPanelUnderpants; + LLPanel *mPanelSkirt; + LLPanel *mPanelAlpha; + LLPanel *mPanelTattoo; + +}; + +#endif diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index 206d8428be..4708d7ba36 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -33,19 +33,22 @@ #include "llpanelgroup.h" +// Library includes #include "llbutton.h" #include "lltabcontainer.h" #include "lltextbox.h" -#include "llviewermessage.h" #include "lluictrlfactory.h" + +// Viewer includes +#include "llviewermessage.h" #include "llviewerwindow.h" #include "llappviewer.h" #include "llnotifications.h" #include "llfloaterreg.h" #include "llfloater.h" +#include "llgroupactions.h" #include "llagent.h" -#include "llstatusbar.h" // can_afford_transaction() #include "llsidetraypanelcontainer.h" @@ -274,46 +277,11 @@ void LLPanelGroup::onBtnApply(void* user_data) LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data); self->apply(); } + void LLPanelGroup::onBtnJoin() { lldebugs << "joining group: " << mID << llendl; - - LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID); - - if (gdatap) - { - S32 cost = gdatap->mMembershipFee; - LLSD args; - args["COST"] = llformat("%d", cost); - LLSD payload; - payload["group_id"] = mID; - - if (can_afford_transaction(cost)) - { - LLNotifications::instance().add("JoinGroupCanAfford", args, payload, LLPanelGroup::joinDlgCB); - } - else - { - LLNotifications::instance().add("JoinGroupCannotAfford", args, payload); - } - } - else - { - llwarns << "LLGroupMgr::getInstance()->getGroupData(" << mID << ") was NULL" << llendl; - } -} -bool LLPanelGroup::joinDlgCB(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - - if (option == 1) - { - // user clicked cancel - return false; - } - - LLGroupMgr::getInstance()->sendGroupMemberJoin(notification["payload"]["group_id"].asUUID()); - return false; + LLGroupActions::join(mID); } void LLPanelGroup::onBtnCancel() @@ -341,18 +309,31 @@ void LLPanelGroup::update(LLGroupChange gc) { childSetValue("group_name", gdatap->mName); + LLButton* btn_join = getChild<LLButton>("btn_join"); + LLUICtrl* join_text = getChild<LLUICtrl>("join_cost_text"); + LLGroupData agent_gdatap; bool is_member = gAgent.getGroupData(mID,agent_gdatap); - LLButton* btn_join = getChild<LLButton>("btn_join"); bool join_btn_visible = !is_member && gdatap->mOpenEnrollment; + btn_join->setVisible(join_btn_visible); + join_text->setVisible(join_btn_visible); + if(join_btn_visible) { LLStringUtil::format_map_t string_args; - string_args["[AMOUNT]"] = llformat("%d", gdatap->mMembershipFee); - std::string fee_buff = getString("group_join_btn", string_args); - btn_join->setLabelSelected(fee_buff); - btn_join->setLabelUnselected(fee_buff); + std::string fee_buff; + if(gdatap->mMembershipFee) + { + string_args["[AMOUNT]"] = llformat("%d", gdatap->mMembershipFee); + fee_buff = getString("group_join_btn", string_args); + + } + else + { + fee_buff = getString("group_join_free", string_args); + } + childSetValue("join_cost_text",fee_buff); } } } @@ -361,6 +342,8 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id) { std::string str_group_id; group_id.toString(str_group_id); + + bool is_same_id = group_id == mID; LLGroupMgr::getInstance()->removeObserver(this); mID = group_id; @@ -429,16 +412,19 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id) getChild<LLUICtrl>("group_name")->setVisible(false); getChild<LLUICtrl>("group_name_editor")->setVisible(true); } - else + else { - 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()); + if(!is_same_id) + { + 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); diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h index 628e2389b6..5c7b0ddd06 100644 --- a/indra/newview/llpanelgroup.h +++ b/indra/newview/llpanelgroup.h @@ -101,8 +101,6 @@ protected: static void onBtnApply(void*); static void onBtnRefresh(void*); - static bool joinDlgCB(const LLSD& notification, const LLSD& response); - void reposButton(const std::string& name); void reposButtons(); diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp index e40fa19bb6..9023afc602 100644 --- a/indra/newview/llpanelgrouplandmoney.cpp +++ b/indra/newview/llpanelgrouplandmoney.cpp @@ -690,7 +690,7 @@ BOOL LLPanelGroupLandMoney::postBuild() if ( mImplementationp->mGroupParcelsp ) { - mImplementationp->mGroupParcelsp->setCommitCallback(boost::bind(&LLButton::setEnabled, mImplementationp->mMapButtonp, true)); + mImplementationp->mGroupParcelsp->setCommitCallback(boost::bind(&LLPanelGroupLandMoney::onLandSelectionChanged, this)); mImplementationp->mGroupParcelsp->setCommitOnSelectionChange(true); } @@ -808,6 +808,11 @@ BOOL LLPanelGroupLandMoney::postBuild() return LLPanelGroupTab::postBuild(); } +void LLPanelGroupLandMoney::onLandSelectionChanged() +{ + mImplementationp->mMapButtonp->setEnabled( mImplementationp->mGroupParcelsp->getItemCount() > 0 ); +} + BOOL LLPanelGroupLandMoney::isVisibleByAgent(LLAgent* agentp) { return mAllowEdit && agentp->isInGroup(mGroupID); @@ -1493,7 +1498,7 @@ void LLPanelGroupLandMoney::setGroupID(const LLUUID& id) if ( mImplementationp->mGroupParcelsp ) { - mImplementationp->mGroupParcelsp->setCommitCallback(boost::bind(&LLButton::setEnabled, mImplementationp->mMapButtonp, true)); + mImplementationp->mGroupParcelsp->setCommitCallback(boost::bind(&LLPanelGroupLandMoney::onLandSelectionChanged, this)); mImplementationp->mGroupParcelsp->setCommitOnSelectionChange(true); } diff --git a/indra/newview/llpanelgrouplandmoney.h b/indra/newview/llpanelgrouplandmoney.h index 0f275ea9a8..7e08d26d6f 100644 --- a/indra/newview/llpanelgrouplandmoney.h +++ b/indra/newview/llpanelgrouplandmoney.h @@ -60,6 +60,8 @@ public: static void processGroupAccountSummaryReply(LLMessageSystem* msg, void** data); virtual void setGroupID(const LLUUID& id); + + virtual void onLandSelectionChanged(); protected: class impl; diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 1d79ea4a21..521e145816 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -35,32 +35,51 @@ #include "llbutton.h" #include "llfloaterreg.h" -#include "lllandmark.h" +#include "llsdutil.h" +#include "llsdutil_math.h" +#include "llaccordionctrltab.h" +#include "llagent.h" +#include "llagentui.h" #include "llfloaterworldmap.h" -#include "llfloaterinventory.h" -#include "llfoldervieweventlistener.h" -#include "lllandmarklist.h" +#include "llfolderviewitem.h" +#include "llinventorysubtreepanel.h" +#include "lllandmarkactions.h" +#include "llplacesinventorybridge.h" #include "llsidetray.h" -#include "lltabcontainer.h" -#include "llworldmap.h" +#include "llviewermenu.h" +#include "llviewerregion.h" // Not yet implemented; need to remove buildPanel() from constructor when we switch //static LLRegisterPanelClassWrapper<LLLandmarksPanel> t_landmarks("panel_landmarks"); +static const std::string OPTIONS_BUTTON_NAME = "options_gear_btn"; +static const std::string ADD_LANDMARK_BUTTON_NAME = "add_landmark_btn"; +static const std::string ADD_FOLDER_BUTTON_NAME = "add_folder_btn"; +static const std::string TRASH_BUTTON_NAME = "trash_btn"; + +static const LLPlacesInventoryBridgeBuilder PLACES_INVENTORY_BUILDER; + +// helper functions +static void filter_list(LLInventorySubTreePanel* inventory_list, const std::string& string); + + LLLandmarksPanel::LLLandmarksPanel() - : LLPanelPlacesTab(), - mInventoryPanel(NULL) + : LLPanelPlacesTab() + , mFavoritesInventoryPanel(NULL) + , mLandmarksInventoryPanel(NULL) + , mMyInventoryPanel(NULL) + , mLibraryInventoryPanel(NULL) + , mCurrentSelectedList(NULL) + , mListCommands(NULL) + , mGearFolderMenu(NULL) + , mGearLandmarkMenu(NULL) { - mSavedFolderState = new LLSaveFolderState(); - mSavedFolderState->setApply(FALSE); - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_landmarks.xml"); } LLLandmarksPanel::~LLLandmarksPanel() { - delete mSavedFolderState; } BOOL LLLandmarksPanel::postBuild() @@ -68,19 +87,15 @@ 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)); + // mast be called before any other initXXX methods to init Gear menu + initListCommandsHandlers(); - 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); + U32 sort_order = gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER); + mSortByDate = sort_order & LLInventoryFilter::SO_DATE; + initFavoritesInventroyPanel(); + initLandmarksInventroyPanel(); + initMyInventroyPanel(); + initLibraryInventroyPanel(); return TRUE; } @@ -88,53 +103,21 @@ BOOL LLLandmarksPanel::postBuild() // 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); + filter_list(mFavoritesInventoryPanel, string); + filter_list(mLandmarksInventoryPanel, string); + filter_list(mMyInventoryPanel, string); + filter_list(mLibraryInventoryPanel, 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) + if (NULL == mCurrentSelectedList) + { + llwarns << "There are no selected list. No actions are performed." << llendl; return; - - LLLandmark* landmark = gLandmarkList.getAsset(inventory_item->getAssetUUID()); + } + LLLandmark* landmark = getCurSelectedLandmark(); if (!landmark) return; @@ -153,9 +136,12 @@ void LLLandmarksPanel::onShowOnMap() // virtual void LLLandmarksPanel::onTeleport() { - LLFolderViewItem* current_item = mInventoryPanel->getRootFolder()->getCurSelectedItem(); + LLFolderViewItem* current_item = getCurSelectedItem(); if (!current_item) + { + llwarns << "There are no selected list. No actions are performed." << llendl; return; + } LLFolderViewEventListener* listenerp = current_item->getListener(); if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK) @@ -164,117 +150,595 @@ void LLLandmarksPanel::onTeleport() } } -/* // virtual -void LLLandmarksPanel::onCopySLURL() +void LLLandmarksPanel::updateVerbs() { - LLFolderViewItem* current_item = mInventoryPanel->getRootFolder()->getCurSelectedItem(); - if (!current_item) + if (!isTabVisible()) return; - LLFolderViewEventListener* listenerp = current_item->getListener(); - if (listenerp->getInventoryType() != LLInventoryType::IT_LANDMARK) - return; + BOOL enabled = isLandmarkSelected(); + mTeleportBtn->setEnabled(enabled); + mShowOnMapBtn->setEnabled(enabled); - LLInventoryItem* inventory_item = gInventory.getItem(listenerp->getUUID()); - if (!inventory_item) - return; + // TODO: mantipov: Uncomment when mShareBtn is supported + // Share button should be enabled when neither a folder nor a landmark is selected + //mShareBtn->setEnabled(NULL != current_item); - LLLandmark* landmark = gLandmarkList.getAsset(inventory_item->getAssetUUID()); - if (!landmark) - return; + updateListCommands(); +} - LLVector3d landmark_global_pos; - if (!landmark->getGlobalPos(landmark_global_pos)) +void LLLandmarksPanel::onSelectionChange(LLInventorySubTreePanel* inventory_list, const std::deque<LLFolderViewItem*> &items, BOOL user_action) +{ + if (user_action && (items.size() > 0)) + { + deselectOtherThan(inventory_list); + mCurrentSelectedList = inventory_list; + } + + LLFolderViewItem* current_item = inventory_list->getRootFolder()->getCurSelectedItem(); + if (!current_item) return; - U64 new_region_handle = to_region_handle(landmark_global_pos); + updateVerbs(); +} + +void LLLandmarksPanel::onSelectorButtonClicked() +{ + // TODO: mantipov: update getting of selected item + // TODO: bind to "i" button + LLFolderViewItem* cur_item = mFavoritesInventoryPanel->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); + } +} + +////////////////////////////////////////////////////////////////////////// +// PROTECTED METHODS +////////////////////////////////////////////////////////////////////////// + +bool LLLandmarksPanel::isLandmarkSelected() const +{ + LLFolderViewItem* current_item = getCurSelectedItem(); + if(current_item && current_item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK) + { + return true; + } + + return false; +} + +LLLandmark* LLLandmarksPanel::getCurSelectedLandmark() const +{ + + LLFolderViewItem* cur_item = getCurSelectedItem(); + if(cur_item && cur_item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK) + { + return LLLandmarkActions::getLandmark(cur_item->getListener()->getUUID()); + } + return NULL; +} + +LLFolderViewItem* LLLandmarksPanel::getCurSelectedItem () const +{ + return mCurrentSelectedList ? mCurrentSelectedList->getRootFolder()->getCurSelectedItem() : NULL; +} + +void LLLandmarksPanel::updateSortOrder(LLInventoryPanel* panel, bool byDate) +{ + if(!panel) return; + + U32 order = panel->getSortOrder(); + if (byDate) + { + panel->setSortOrder( order | LLInventoryFilter::SO_DATE ); + } + else + { + panel->setSortOrder( order & ~LLInventoryFilter::SO_DATE ); + } +} - LLWorldMap::url_callback_t cb = boost::bind( - &LLPanelPlacesTab::onRegionResponse, this, - landmark_global_pos, _1, _2, _3, _4); +// virtual +void LLLandmarksPanel::processParcelInfo(const LLParcelData& parcel_data) +{ + //this function will be called after user will try to create a pick for selected landmark. + // We have to make request to sever to get parcel_id and snaption_id. + if(isLandmarkSelected()) + { + LLLandmark* landmark = getCurSelectedLandmark(); + LLFolderViewItem* cur_item = getCurSelectedItem(); + LLUUID id = cur_item->getListener()->getUUID(); + LLInventoryItem* inv_item = mCurrentSelectedList->getModel()->getItem(id); + if(landmark) + { + LLPanelPickEdit* panel_pick = LLPanelPickEdit::create(); + LLVector3d landmark_global_pos; + landmark->getGlobalPos(landmark_global_pos); + + // let's toggle pick panel into panel places + LLPanel* panel_places = LLSideTray::getInstance()->getChild<LLPanel>("panel_places");//-> sidebar_places + panel_places->addChild(panel_pick); + LLRect paren_rect(panel_places->getRect()); + panel_pick->reshape(paren_rect.getWidth(),paren_rect.getHeight(), TRUE); + panel_pick->setRect(paren_rect); + panel_pick->onOpen(LLSD()); + + LLPickData data; + data.pos_global = landmark_global_pos; + data.name = cur_item->getName(); + data.desc = inv_item->getDescription(); + data.snapshot_id = parcel_data.snapshot_id; + data.parcel_id = parcel_data.parcel_id; + panel_pick->setPickData(&data); + + LLSD params; + params["parcel_id"] =parcel_data.parcel_id; + /* set exit callback to get back onto panel places + in callback we will make cleaning up( delete pick_panel instance, + remove landmark panel from observer list + */ + panel_pick->setExitCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this, + panel_pick, panel_places,params)); + panel_pick->setSaveCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this, + panel_pick, panel_places,params)); + } + } +} - LLWorldMap::getInstance()->sendHandleRegionRequest(new_region_handle, cb, std::string("unused"), false); +// virtual +void LLLandmarksPanel::setParcelID(const LLUUID& parcel_id) +{ + if (!parcel_id.isNull()) + { + LLRemoteParcelInfoProcessor::getInstance()->addObserver(parcel_id, this); + LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(parcel_id); + } } -*/ // virtual -void LLLandmarksPanel::updateVerbs() +void LLLandmarksPanel::setErrorStatus(U32 status, const std::string& reason) { - if (!isTabVisible()) - return; + llerrs<< "Can't handle remote parcel request."<< " Http Status: "<< status << ". Reason : "<< reason<<llendl; +} - BOOL enabled = FALSE; - LLFolderViewItem* current_item = mInventoryPanel->getRootFolder()->getCurSelectedItem(); +////////////////////////////////////////////////////////////////////////// +// PRIVATE METHODS +////////////////////////////////////////////////////////////////////////// + +void LLLandmarksPanel::initFavoritesInventroyPanel() +{ + mFavoritesInventoryPanel = getChild<LLInventorySubTreePanel>("favorites_list"); + + LLUUID start_folder_id = mFavoritesInventoryPanel->getModel()->findCategoryUUIDForType(LLAssetType::AT_FAVORITE); + + initLandmarksPanel(mFavoritesInventoryPanel, start_folder_id); + + initAccordion("tab_favorites", mFavoritesInventoryPanel); +} + +void LLLandmarksPanel::initLandmarksInventroyPanel() +{ + mLandmarksInventoryPanel = getChild<LLInventorySubTreePanel>("landmarks_list"); + + LLUUID start_folder_id = mLandmarksInventoryPanel->getModel()->findCategoryUUIDForType(LLAssetType::AT_LANDMARK); + + initLandmarksPanel(mLandmarksInventoryPanel, start_folder_id); + mLandmarksInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS); + + // subscribe to have auto-rename functionality while creating New Folder + mLandmarksInventoryPanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mLandmarksInventoryPanel, _1, _2)); + + initAccordion("tab_landmarks", mLandmarksInventoryPanel); +} + +void LLLandmarksPanel::initMyInventroyPanel() +{ + mMyInventoryPanel= getChild<LLInventorySubTreePanel>("my_inventory_list"); + + LLUUID start_folder_id = mMyInventoryPanel->getModel()->getRootFolderID(); + + initLandmarksPanel(mMyInventoryPanel, start_folder_id); + + initAccordion("tab_inventory", mMyInventoryPanel); +} + +void LLLandmarksPanel::initLibraryInventroyPanel() +{ + mLibraryInventoryPanel = getChild<LLInventorySubTreePanel>("library_list"); + + LLUUID start_folder_id = mLibraryInventoryPanel->getModel()->getLibraryRootFolderID(); + + initLandmarksPanel(mLibraryInventoryPanel, start_folder_id); + + initAccordion("tab_library", mLibraryInventoryPanel); +} + + +void LLLandmarksPanel::initLandmarksPanel(LLInventorySubTreePanel* inventory_list, const LLUUID& start_folder_id) +{ + inventory_list->buildSubtreeViewsFor(start_folder_id, &PLACES_INVENTORY_BUILDER); + + inventory_list->setFilterTypes(0x1 << LLInventoryType::IT_LANDMARK); + inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, inventory_list, _1, _2)); + + inventory_list->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); + updateSortOrder(inventory_list, mSortByDate); + + LLPlacesFolderView* root_folder = dynamic_cast<LLPlacesFolderView*>(inventory_list->getRootFolder()); + if (root_folder) + { + root_folder->setupMenuHandle(LLInventoryType::IT_CATEGORY, mGearFolderMenu->getHandle()); + root_folder->setupMenuHandle(LLInventoryType::IT_LANDMARK, mGearLandmarkMenu->getHandle()); + } +} + +void LLLandmarksPanel::initAccordion(const std::string& accordion_tab_name, LLInventorySubTreePanel* inventory_list) +{ + LLAccordionCtrlTab* accordion_tab = getChild<LLAccordionCtrlTab>(accordion_tab_name); + accordion_tab->setDropDownStateChangedCallback( + boost::bind(&LLLandmarksPanel::onAccordionExpandedCollapsed, this, _2, inventory_list)); +} + +void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLInventorySubTreePanel* inventory_list) +{ + bool expanded = param.asBoolean(); + + if(!expanded && (mCurrentSelectedList == inventory_list)) + { + inventory_list->getRootFolder()->clearSelection(); + + mCurrentSelectedList = NULL; + updateVerbs(); + } +} + +void LLLandmarksPanel::deselectOtherThan(const LLInventorySubTreePanel* inventory_list) +{ + if (inventory_list != mFavoritesInventoryPanel) + { + mFavoritesInventoryPanel->getRootFolder()->clearSelection(); + } + + if (inventory_list != mLandmarksInventoryPanel) + { + mLandmarksInventoryPanel->getRootFolder()->clearSelection(); + } + if (inventory_list != mMyInventoryPanel) + { + mMyInventoryPanel->getRootFolder()->clearSelection(); + } + if (inventory_list != mLibraryInventoryPanel) + { + mLibraryInventoryPanel->getRootFolder()->clearSelection(); + } +} + +// List Commands Handlers +void LLLandmarksPanel::initListCommandsHandlers() +{ + mListCommands = getChild<LLPanel>("bottom_panel"); + + mListCommands->childSetAction(OPTIONS_BUTTON_NAME, boost::bind(&LLLandmarksPanel::onActionsButtonClick, this)); + mListCommands->childSetAction(ADD_LANDMARK_BUTTON_NAME, boost::bind(&LLLandmarksPanel::onAddLandmarkButtonClick, this)); + mListCommands->childSetAction(ADD_FOLDER_BUTTON_NAME, boost::bind(&LLLandmarksPanel::onAddFolderButtonClick, this)); + mListCommands->childSetAction(TRASH_BUTTON_NAME, boost::bind(&LLLandmarksPanel::onTrashButtonClick, this)); + + + mCommitCallbackRegistrar.add("Places.LandmarksGear.Add.Action", boost::bind(&LLLandmarksPanel::onAddAction, this, _2)); + mCommitCallbackRegistrar.add("Places.LandmarksGear.CopyPaste.Action", boost::bind(&LLLandmarksPanel::onCopyPasteAction, this, _2)); + mCommitCallbackRegistrar.add("Places.LandmarksGear.Custom.Action", boost::bind(&LLLandmarksPanel::onCustomAction, this, _2)); + mCommitCallbackRegistrar.add("Places.LandmarksGear.Folding.Action", boost::bind(&LLLandmarksPanel::onFoldingAction, this, _2)); + mEnableCallbackRegistrar.add("Places.LandmarksGear.Enable", boost::bind(&LLLandmarksPanel::isActionEnabled, this, _2)); + mGearLandmarkMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_places_gear_landmark.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mGearFolderMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_places_gear_folder.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); +} + + +void LLLandmarksPanel::updateListCommands() +{ + // TODO: should be false when "Received" folder is selected + bool add_folder_enabled = mCurrentSelectedList == mLandmarksInventoryPanel; + bool trash_enabled = false; // TODO: should be false when "Received" folder is selected + + LLFolderViewItem* current_item = getCurSelectedItem(); + if (current_item) { LLFolderViewEventListener* listenerp = current_item->getListener(); if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK) { - enabled = TRUE; + trash_enabled = mCurrentSelectedList != mLibraryInventoryPanel; } } - mTeleportBtn->setEnabled(enabled); - mShowOnMapBtn->setEnabled(enabled); + // keep Options & Add Landmark buttons always enabled + mListCommands->childSetEnabled(ADD_FOLDER_BUTTON_NAME, add_folder_enabled); + mListCommands->childSetEnabled(TRASH_BUTTON_NAME, trash_enabled); } -void LLLandmarksPanel::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action) +void LLLandmarksPanel::onActionsButtonClick() { - LLFolderViewItem* current_item = mInventoryPanel->getRootFolder()->getCurSelectedItem(); - if (!current_item) + LLFolderViewItem* cur_item = NULL; + if(mCurrentSelectedList) + cur_item = mCurrentSelectedList->getRootFolder()->getCurSelectedItem(); + + if(!cur_item) return; - - LLFolderViewEventListener* listenerp = current_item->getListener(); + + LLFolderViewEventListener* listenerp = cur_item->getListener(); + + LLMenuGL* menu =NULL; if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK) { - S32 bottom = 0; - LLFolderViewItem* folder = current_item->getParentFolder(); + menu = mGearLandmarkMenu; + } + else if (listenerp->getInventoryType() == LLInventoryType::IT_CATEGORY) + { + mGearFolderMenu->getChild<LLMenuItemCallGL>("expand")->setVisible(!cur_item->isOpen()); + mGearFolderMenu->getChild<LLMenuItemCallGL>("collapse")->setVisible(cur_item->isOpen()); + menu = mGearFolderMenu; + } + if(menu) + { + menu->buildDrawLabels(); + menu->updateParent(LLMenuGL::sMenuContainer); + LLView* actions_btn = getChild<LLView>(OPTIONS_BUTTON_NAME); + S32 menu_x, menu_y; + actions_btn->localPointToOtherView(0,actions_btn->getRect().getHeight(),&menu_x,&menu_y, this); + menu_y += menu->getRect().getHeight(); + LLMenuGL::showPopup(this, menu, menu_x,menu_y); + } +} - while ( folder->getParentFolder() != NULL ) +void LLLandmarksPanel::onAddLandmarkButtonClick() const +{ + if(LLLandmarkActions::landmarkAlreadyExists()) + { + std::string location; + LLAgentUI::buildLocationString(location, LLAgentUI::LOCATION_FORMAT_FULL); + llwarns<<" Landmark already exists at location: "<< location<<llendl; + return; + } + LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark")); +} + +void LLLandmarksPanel::onAddFolderButtonClick() const +{ + LLFolderViewItem* item = getCurSelectedItem(); + if(item && mCurrentSelectedList == mLandmarksInventoryPanel) + { + LLFolderBridge *parentBridge = NULL; + if(item-> getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK) + { + parentBridge = dynamic_cast<LLFolderBridge*>(item->getParentFolder()->getListener()); + /*WORKAROUND:* + LLFolderView::doIdle() is calling in each frame, + it changes selected items before LLFolderView::startRenamingSelectedItem. + To avoid it we have to change keyboardFocus. + */ + gFocusMgr.setKeyboardFocus(item->getParentFolder()); + } + else if (item-> getListener()->getInventoryType() == LLInventoryType::IT_CATEGORY) { - bottom += folder->getRect().mBottom; - folder = folder->getParentFolder(); + parentBridge = dynamic_cast<LLFolderBridge*>(item->getListener()); + gFocusMgr.setKeyboardFocus(item); } + menu_create_inventory_item(mCurrentSelectedList->getRootFolder(),parentBridge, LLSD("category")); + } +} - LLRect rect = current_item->getRect(); - LLRect btn_rect( - rect.mRight - mActionBtn->getRect().getWidth(), - bottom + rect.mTop, - rect.mRight, - bottom + rect.mBottom); +void LLLandmarksPanel::onTrashButtonClick() const +{ + if(!mCurrentSelectedList) return; - mActionBtn->setRect(btn_rect); + mCurrentSelectedList->getRootFolder()->doToSelected(mCurrentSelectedList->getModel(), "delete"); +} - if (!mActionBtn->getVisible()) - mActionBtn->setVisible(TRUE); +void LLLandmarksPanel::onAddAction(const LLSD& userdata) const +{ + std::string command_name = userdata.asString(); + if("add_landmark" == command_name) + { + onAddLandmarkButtonClick(); + } + else if ("category" == command_name) + { + onAddFolderButtonClick(); + } +} + +void LLLandmarksPanel::onCopyPasteAction(const LLSD& userdata) const +{ + if(!mCurrentSelectedList) + return; + std::string command_name = userdata.asString(); + if("copy_slurl" == command_name) + { + LLFolderViewItem* cur_item = getCurSelectedItem(); + if(cur_item) + LLLandmarkActions::copySLURLtoClipboard(cur_item->getListener()->getUUID()); + } + else if ( "paste" == command_name) + { + mCurrentSelectedList->getRootFolder()->paste(); + } + else if ( "cut" == command_name) + { + mCurrentSelectedList->getRootFolder()->cut(); } else { - if (mActionBtn->getVisible()) - mActionBtn->setVisible(FALSE); + mCurrentSelectedList->getRootFolder()->doToSelected(mCurrentSelectedList->getModel(),command_name); } - - updateVerbs(); } -void LLLandmarksPanel::onSelectorButtonClicked() +void LLLandmarksPanel::onFoldingAction(const LLSD& userdata) { - LLFolderViewItem* cur_item = mInventoryPanel->getRootFolder()->getCurSelectedItem(); + if(!mCurrentSelectedList) return; - LLFolderViewEventListener* listenerp = cur_item->getListener(); - if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK) + LLFolderView* root_folder = mCurrentSelectedList->getRootFolder(); + std::string command_name = userdata.asString(); + + if ("expand_all" == command_name) { - LLSD key; - key["type"] = "landmark"; - key["id"] = listenerp->getUUID(); + root_folder->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN); + root_folder->arrangeAll(); + } + else if ("collapse_all" == command_name) + { + root_folder->closeAllFolders(); + } + else if ( "sort_by_date" == command_name) + { + mSortByDate = !mSortByDate; + updateSortOrder(mFavoritesInventoryPanel, mSortByDate); + updateSortOrder(mLandmarksInventoryPanel, mSortByDate); + updateSortOrder(mMyInventoryPanel, mSortByDate); + updateSortOrder(mLibraryInventoryPanel, mSortByDate); + } + else + { + root_folder->doToSelected(&gInventory, userdata); + } +} - LLSideTray::getInstance()->showPanel("panel_places", key); +bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const +{ + std::string command_name = userdata.asString(); + if("category" == command_name) + { + return mCurrentSelectedList == mLandmarksInventoryPanel; + } + else if("paste" == command_name) + { + return mCurrentSelectedList ? mCurrentSelectedList->getRootFolder()->canPaste() : false; + } + else if ( "sort_by_date" == command_name) + { + return mSortByDate; + } + // do not allow teleport and more info for multi-selections + else if ("teleport" == command_name || "more_info" == command_name) + { + return mCurrentSelectedList ? + static_cast<LLPlacesFolderView*>(mCurrentSelectedList->getRootFolder())->getSelectedCount() == 1 : false; + } + // we can add folder, or change item/folder only in Landmarks Accordion + else if ("add_folder" == command_name || "rename" == command_name || "delete" == command_name) + { + return mLandmarksInventoryPanel == mCurrentSelectedList; + } + + return true; +} + +void LLLandmarksPanel::onCustomAction(const LLSD& userdata) +{ + LLFolderViewItem* cur_item = getCurSelectedItem(); + if(!cur_item) + return ; + std::string command_name = userdata.asString(); + if("more_info" == command_name) + { + cur_item->getListener()->performAction(mCurrentSelectedList->getRootFolder(),mCurrentSelectedList->getModel(),"about"); + } + else if ("teleport" == command_name) + { + onTeleport(); + } + else if ("show_on_map" == command_name) + { + onShowOnMap(); + } + else if ("create_pick" == command_name) + { + LLLandmark* landmark = getCurSelectedLandmark(); + if(!landmark) return; + + LLViewerRegion* region = gAgent.getRegion(); + if (!region) return; + + LLGlobalVec pos_global; + LLUUID region_id; + landmark->getGlobalPos(pos_global); + landmark->getRegionID(region_id); + LLVector3 region_pos((F32)fmod(pos_global.mdV[VX], (F64)REGION_WIDTH_METERS), + (F32)fmod(pos_global.mdV[VY], (F64)REGION_WIDTH_METERS), + (F32)pos_global.mdV[VZ]); + + LLSD body; + std::string url = region->getCapability("RemoteParcelRequest"); + if (!url.empty()) + { + body["location"] = ll_sd_from_vector3(region_pos); + 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 + { + llwarns << "Can't create pick for landmark for region" << region_id + << ". Region: " << region->getName() + << " does not support RemoteParcelRequest" << llendl; + } } } -void LLLandmarksPanel::setSelectedItem(const LLUUID& obj_id) +void LLLandmarksPanel::onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params) { - mInventoryPanel->setSelection(obj_id, FALSE); + pick_panel->setVisible(FALSE); + owner->removeChild(pick_panel); + //we need remove observer to avoid processParcelInfo in the future. + LLRemoteParcelInfoProcessor::getInstance()->removeObserver(params["parcel_id"].asUUID(), this); + + delete pick_panel; + pick_panel = NULL; +} + + +////////////////////////////////////////////////////////////////////////// +// HELPER FUNCTIONS +////////////////////////////////////////////////////////////////////////// +static void filter_list(LLInventorySubTreePanel* inventory_list, const std::string& string) +{ + if (string == "") + { + inventory_list->setFilterSubString(LLStringUtil::null); + + // re-open folders that were initially open + inventory_list->restoreFolderState(); + } + + gInventory.startBackgroundFetch(); + + if (inventory_list->getFilterSubString().empty() && string.empty()) + { + // current filter and new filter empty, do nothing + return; + } + + // save current folder open state if no filter currently applied + if (inventory_list->getRootFolder()->getFilterSubString().empty()) + { + inventory_list->saveFolderState(); + } + + // set new filter string + inventory_list->setFilterSubString(string); } +// EOF diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index 14cbbd6123..389a04a76f 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -33,14 +33,20 @@ #ifndef LL_LLPANELLANDMARKS_H #define LL_LLPANELLANDMARKS_H +#include "lllandmark.h" + +// newview #include "llinventorymodel.h" #include "llpanelplacestab.h" +#include "llpanelpick.h" +#include "llremoteparcelrequest.h" class LLFolderViewItem; +class LLMenuGL; class LLInventoryPanel; -class LLSaveFolderState; +class LLInventorySubTreePanel; -class LLLandmarksPanel : public LLPanelPlacesTab +class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver { public: LLLandmarksPanel(); @@ -50,17 +56,60 @@ public: /*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 onSelectionChange(LLInventorySubTreePanel* inventory_list, const std::deque<LLFolderViewItem*> &items, BOOL user_action); void onSelectorButtonClicked(); - void setSelectedItem(const LLUUID& obj_id); + +protected: + /** + * @return true - if current selected panel is not null and selected item is a landmark + */ + bool isLandmarkSelected() const; + LLLandmark* getCurSelectedLandmark() const; + LLFolderViewItem* getCurSelectedItem () const; + void updateSortOrder(LLInventoryPanel* panel, bool byDate); + //LLRemoteParcelInfoObserver interface + /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); + /*virtual*/ void setParcelID(const LLUUID& parcel_id); + /*virtual*/ void setErrorStatus(U32 status, const std::string& reason); + private: - LLInventoryPanel* mInventoryPanel; - LLSaveFolderState* mSavedFolderState; - LLButton* mActionBtn; + void initFavoritesInventroyPanel(); + void initLandmarksInventroyPanel(); + void initMyInventroyPanel(); + void initLibraryInventroyPanel(); + void initLandmarksPanel(LLInventorySubTreePanel* inventory_list, const LLUUID& start_folder_id); + void initAccordion(const std::string& accordion_tab_name, LLInventorySubTreePanel* inventory_list); + void onAccordionExpandedCollapsed(const LLSD& param, LLInventorySubTreePanel* inventory_list); + void deselectOtherThan(const LLInventorySubTreePanel* inventory_list); + + // List Commands Handlers + void initListCommandsHandlers(); + void updateListCommands(); + void onActionsButtonClick(); + void onAddLandmarkButtonClick() const; + void onAddFolderButtonClick() const; + void onTrashButtonClick() const; + void onAddAction(const LLSD& command_name) const; + void onCopyPasteAction(const LLSD& command_name) const; + void onFoldingAction(const LLSD& command_name); + bool isActionEnabled(const LLSD& command_name) const; + void onCustomAction(const LLSD& command_name); + void onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params); + +private: + LLInventorySubTreePanel* mFavoritesInventoryPanel; + LLInventorySubTreePanel* mLandmarksInventoryPanel; + LLInventorySubTreePanel* mMyInventoryPanel; + LLInventorySubTreePanel* mLibraryInventoryPanel; + LLMenuGL* mGearLandmarkMenu; + LLMenuGL* mGearFolderMenu; + LLInventorySubTreePanel* mCurrentSelectedList; + + LLPanel* mListCommands; + bool mSortByDate; }; #endif //LL_LLPANELLANDMARKS_H diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index c94c38983d..9dc80c0515 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -87,7 +87,39 @@ protected: } }; +/** Compares avatar items by online status, then by name */ +class LLAvatarItemStatusComparator : public LLAvatarItemComparator +{ +public: + LLAvatarItemStatusComparator() {}; + +protected: + /** + * @return true if item1 < item2, false otherwise + */ + virtual bool doCompare(const LLAvatarListItem* item1, const LLAvatarListItem* item2) const + { + LLAvatarTracker& at = LLAvatarTracker::instance(); + bool online1 = at.isBuddyOnline(item1->getAvatarId()); + bool online2 = at.isBuddyOnline(item2->getAvatarId()); + + if (online1 == online2) + { + std::string name1 = item1->getAvatarName(); + std::string name2 = item2->getAvatarName(); + + LLStringUtil::toUpper(name1); + LLStringUtil::toUpper(name2); + + return name1 < name2; + } + + return online1 > online2; + } +}; + static const LLAvatarItemRecentComparator RECENT_COMPARATOR; +static const LLAvatarItemStatusComparator STATUS_COMPARATOR; static LLRegisterPanelClassWrapper<LLPanelPeople> t_people("panel_people"); @@ -395,7 +427,8 @@ BOOL LLPanelPeople::postBuild() mNearbyList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu); mRecentList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu); - mRecentList->setComparator(&RECENT_COMPARATOR); + setSortOrder(mRecentList, (ESortOrder)gSavedSettings.getU32("RecentPeopleSortOrder"), false); + setSortOrder(mAllFriendList, (ESortOrder)gSavedSettings.getU32("FriendsSortOrder"), false); LLPanel* groups_panel = getChild<LLPanel>(GROUP_TAB_NAME); groups_panel->childSetAction("activate_btn", boost::bind(&LLPanelPeople::onActivateButtonClicked, this)); @@ -446,12 +479,16 @@ BOOL LLPanelPeople::postBuild() // Create menus. LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_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.Groups.ViewSort.Action", boost::bind(&LLPanelPeople::onGroupsViewSortMenuItemClicked, this, _2)); registrar.add("People.Recent.ViewSort.Action", boost::bind(&LLPanelPeople::onRecentViewSortMenuItemClicked, this, _2)); + + enable_registrar.add("People.Friends.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemCheck, this, _2)); + enable_registrar.add("People.Recent.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onRecentViewSortMenuItemCheck, this, _2)); LLMenuGL* plus_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_group_plus.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mGroupPlusMenuHandle = plus_menu->getHandle(); @@ -672,6 +709,42 @@ void LLPanelPeople::showGroupMenu(LLMenuGL* menu) LLMenuGL::showPopup(parent_panel, menu, menu_x, menu_y); } +void LLPanelPeople::setSortOrder(LLAvatarList* list, ESortOrder order, bool save) +{ + switch (order) + { + case E_SORT_BY_NAME: + list->sortByName(); + break; + case E_SORT_BY_STATUS: + list->setComparator(&STATUS_COMPARATOR); + list->sort(); + break; + case E_SORT_BY_MOST_RECENT: + list->setComparator(&RECENT_COMPARATOR); + list->sort(); + break; + default: + llwarns << "Unrecognized people sort order for " << list->getName() << llendl; + return; + } + + if (save) + { + std::string setting; + + if (list == mAllFriendList || list == mOnlineFriendList) + setting = "FriendsSortOrder"; + else if (list == mRecentList) + setting = "RecentPeopleSortOrder"; + else if (list == mNearbyList) + setting = "NearbyPeopleSortOrder"; // *TODO: unused by current implementation + + if (!setting.empty()) + gSavedSettings.setU32(setting, order); + } +} + void LLPanelPeople::onVisibilityChange(const LLSD& new_visibility) { if (new_visibility.asBoolean() == FALSE) @@ -854,9 +927,11 @@ void LLPanelPeople::onFriendsViewSortMenuItemClicked(const LLSD& userdata) if (chosen_item == "sort_name") { + setSortOrder(mAllFriendList, E_SORT_BY_NAME); } else if (chosen_item == "sort_status") { + setSortOrder(mAllFriendList, E_SORT_BY_STATUS); } else if (chosen_item == "view_icons") { @@ -900,18 +975,44 @@ void LLPanelPeople::onRecentViewSortMenuItemClicked(const LLSD& userdata) if (chosen_item == "sort_recent") { - mRecentList->setComparator(&RECENT_COMPARATOR); - mRecentList->sort(); + setSortOrder(mRecentList, E_SORT_BY_MOST_RECENT); } else if (chosen_item == "sort_name") { - mRecentList->sortByName(); + setSortOrder(mRecentList, E_SORT_BY_NAME); } else if (chosen_item == "view_icons") { + // *TODO: implement showing/hiding icons } } +bool LLPanelPeople::onFriendsViewSortMenuItemCheck(const LLSD& userdata) +{ + std::string item = userdata.asString(); + U32 sort_order = gSavedSettings.getU32("FriendsSortOrder"); + + if (item == "sort_name") + return sort_order == E_SORT_BY_NAME; + if (item == "sort_status") + return sort_order == E_SORT_BY_STATUS; + + return false; +} + +bool LLPanelPeople::onRecentViewSortMenuItemCheck(const LLSD& userdata) +{ + std::string item = userdata.asString(); + U32 sort_order = gSavedSettings.getU32("RecentPeopleSortOrder"); + + if (item == "sort_recent") + return sort_order == E_SORT_BY_MOST_RECENT; + if (item == "sort_name") + return sort_order == E_SORT_BY_NAME; + + return false; +} + void LLPanelPeople::onCallButtonClicked() { // *TODO: not implemented yet diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index 03802015ce..aa78080d7e 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -57,6 +57,13 @@ public: class Updater; private: + + typedef enum e_sort_oder { + E_SORT_BY_NAME = 0, + E_SORT_BY_STATUS = 1, + E_SORT_BY_MOST_RECENT = 2, + } ESortOrder; + // methods indirectly called by the updaters void updateFriendList(); void updateNearbyList(); @@ -69,6 +76,7 @@ private: 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 setSortOrder(LLAvatarList* list, ESortOrder order, bool save = true); void onVisibilityChange( const LLSD& new_visibility); @@ -104,6 +112,9 @@ private: void onGroupsViewSortMenuItemClicked(const LLSD& userdata); void onRecentViewSortMenuItemClicked(const LLSD& userdata); + bool onFriendsViewSortMenuItemCheck(const LLSD& userdata); + bool onRecentViewSortMenuItemCheck(const LLSD& userdata); + // misc callbacks static void onAvatarPicked( const std::vector<std::string>& names, diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp index 424e453a2f..664ebfd7a4 100644 --- a/indra/newview/llpanelpick.cpp +++ b/indra/newview/llpanelpick.cpp @@ -68,265 +68,161 @@ std::string SET_LOCATION_NOTICE("(will update after save)"); -LLPanelPick::LLPanelPick(BOOL edit_mode/* = FALSE */) -: LLPanel(), LLAvatarPropertiesObserver(), LLRemoteParcelInfoObserver(), - mEditMode(edit_mode), - mSnapshotCtrl(NULL), - mPickId(LLUUID::null), - mCreatorId(LLUUID::null), - mDataReceived(FALSE), - mIsPickNew(false), - mLocationChanged(false) -{ - if (edit_mode) - { - LLUICtrlFactory::getInstance()->buildPanel(this, XML_PANEL_EDIT_PICK); - LLAvatarPropertiesProcessor::instance().addObserver(gAgentID, this); - } - else - { - LLUICtrlFactory::getInstance()->buildPanel(this, XML_PANEL_PICK_INFO); - } +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +//static +LLPanelPickInfo* LLPanelPickInfo::create() +{ + LLPanelPickInfo* panel = new LLPanelPickInfo(); + LLUICtrlFactory::getInstance()->buildPanel(panel, XML_PANEL_PICK_INFO); + return panel; } -LLPanelPick::~LLPanelPick() +LLPanelPickInfo::LLPanelPickInfo() + : LLPanel() + , LLAvatarPropertiesObserver() + , LLRemoteParcelInfoObserver() + , mAvatarId(LLUUID::null) + , mSnapshotCtrl(NULL) + , mPickId(LLUUID::null) { - if (mCreatorId.notNull()) LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorId, this); } -void LLPanelPick::reset() +LLPanelPickInfo::~LLPanelPickInfo() { - 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); - - mDataReceived = FALSE; - - mPosGlobal.clearVec(); - - childSetValue("maturity", ""); + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this); } -BOOL LLPanelPick::postBuild() +void LLPanelPickInfo::onOpen(const LLSD& key) { - mSnapshotCtrl = getChild<LLTextureCtrl>(XML_SNAPSHOT); - - if (mEditMode) - { - enableSaveButton(FALSE); - - mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelPick::onPickChanged, this, _1)); - - LLLineEditor* line_edit = getChild<LLLineEditor>("pick_name"); - line_edit->setKeystrokeCallback(boost::bind(&LLPanelPick::onPickChanged, this, _1), NULL); - - LLTextEditor* text_edit = getChild<LLTextEditor>("pick_desc"); - text_edit->setKeystrokeCallback(boost::bind(&LLPanelPick::onPickChanged, this, _1)); - - 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)); - - mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelPick::childSetVisible, this, "edit_icon", true)); - mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelPick::childSetVisible, this, "edit_icon", false)); - } - else + LLUUID avatar_id = key["avatar_id"]; + if(avatar_id.isNull()) { - 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)); - + return; } - // EXT-822. We have to process "Back" button click in both Edit & View Modes - if (!mBackCb.empty()) + if(getAvatarId().notNull()) { - LLButton* button = findChild<LLButton>("back_btn"); - if (button) button->setClickedCallback(mBackCb); + LLAvatarPropertiesProcessor::getInstance()->removeObserver( + getAvatarId(), this); } - return TRUE; -} - -void LLPanelPick::init(LLUUID creator_id, LLUUID pick_id) -{ - mCreatorId = creator_id; - mPickId = pick_id; - - //*TODO consider removing this, already called by setEditMode() - updateButtons(); - - requestData(); -} - -void LLPanelPick::requestData() -{ - mDataReceived = FALSE; - LLAvatarPropertiesProcessor::instance().addObserver(mCreatorId, this); - LLAvatarPropertiesProcessor::instance().sendPickInfoRequest(mCreatorId, mPickId); -} - -void LLPanelPick::init(LLPickData *pick_data) -{ - mPickId = pick_data->pick_id; - mCreatorId = pick_data->creator_id; + setAvatarId(avatar_id); - setPickName(pick_data->name); - setPickDesc(pick_data->desc); - - mSnapshotCtrl->setImageAssetID(pick_data->snapshot_id); + resetData(); + resetControls(); - //*HACK see reset() where the texture control was set to FALSE - mSnapshotCtrl->setValid(TRUE); + setPickId(key["pick_id"]); + setPickName(key["pick_name"]); + setPickDesc(key["pick_desc"]); + setSnapshotId(key["snapshot_id"]); - mPosGlobal = pick_data->pos_global; - mSimName = pick_data->sim_name; - mParcelId = pick_data->parcel_id; - - setPickLocation(createLocationText(pick_data->user_name, pick_data->original_name, - pick_data->sim_name, pick_data->pos_global)); + LLAvatarPropertiesProcessor::getInstance()->addObserver( + getAvatarId(), this); + LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest( + getAvatarId(), getPickId()); } -void LLPanelPick::prepareNewPick(const LLVector3d pos_global, - const std::string& name, - const std::string& desc, - const LLUUID& snapshot_id, - const LLUUID& parcel_id) +BOOL LLPanelPickInfo::postBuild() { - mPickId.generate(); - mCreatorId = gAgent.getID(); - mPosGlobal = pos_global; - setPickName(name); - setPickDesc(desc); - mSnapshotCtrl->setImageAssetID(snapshot_id); - mParcelId = parcel_id; - - setPickLocation(createLocationText(std::string(""), SET_LOCATION_NOTICE, name, pos_global)); + mSnapshotCtrl = getChild<LLTextureCtrl>(XML_SNAPSHOT); childSetLabelArg(XML_BTN_SAVE, SAVE_BTN_LABEL, std::string("Pick")); - mIsPickNew = true; + childSetAction("teleport_btn", boost::bind(&LLPanelPickInfo::onClickTeleport, this)); + childSetAction("show_on_map_btn", boost::bind(&LLPanelPickInfo::onClickMap, this)); + childSetAction("back_btn", boost::bind(&LLPanelPickInfo::onClickBack, this)); + + return TRUE; } -// Fill in some reasonable defaults for a new pick. -void LLPanelPick::prepareNewPick() +void LLPanelPickInfo::processProperties(void* data, EAvatarProcessorType type) { - // Try to fill in the current parcel - LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - if (parcel) + if(APT_PICK_INFO != type) { - prepareNewPick(gAgent.getPositionGlobal(), - parcel->getName(), - parcel->getDesc(), - parcel->getSnapshotID(), - parcel->getID()); + return; } -} - -/*virtual*/ void LLPanelPick::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); - mDataReceived = TRUE; - LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorId, this); - - if (!mEditMode) + LLPickData* pick_info = static_cast<LLPickData*>(data); + if(!pick_info + || pick_info->creator_id != getAvatarId() + || pick_info->pick_id != getPickId()) { - LLRemoteParcelInfoProcessor::getInstance()->addObserver(pick_data->parcel_id, this); - LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(pick_data->parcel_id); + return; } -} + setSnapshotId(pick_info->snapshot_id); + setPickName(pick_info->name); + setPickDesc(pick_info->desc); + setPosGlobal(pick_info->pos_global); + setPickLocation(createLocationText(pick_info->user_name, pick_info->original_name, + pick_info->sim_name, pick_info->pos_global)); -void LLPanelPick::setEditMode( BOOL edit_mode ) -{ - if (mEditMode == edit_mode) return; - mEditMode = edit_mode; - - // preserve data before killing controls - LLUUID snapshot_id = mSnapshotCtrl->getImageAssetID(); - LLRect old_rect = getRect(); - - deleteAllChildren(); + // *NOTE dzaporozhan + // We want to keep listening to APT_PICK_INFO because user may + // edit the Pick and we have to update Pick info panel. + // revomeObserver is called from onClickBack +} - // *WORKAROUND: for EXT-931. Children are created for both XML_PANEL_EDIT_PICK & XML_PANEL_PICK_INFO files - // The reason is in LLPanel::initPanelXML called from the LLUICtrlFactory::buildPanel(). - // It creates children from the xml file stored while previous initializing in the "mXMLFilename" member - // and then in creates children from the parameters passed from the LLUICtrlFactory::buildPanel(). - // Xml filename is stored after LLPanel::initPanelXML is called (added with export-from-ll/viewer-2-0, r1594 into LLUICtrlFactory::buildPanel & LLUICtrlFactory::buildFloater) - // In case panel creates children from the different xml files they appear from both files. - // So, let clear xml filename related to this instance. - setXMLFilename(""); +void LLPanelPickInfo::setExitCallback(const commit_callback_t& cb) +{ + getChild<LLButton>("back_btn")->setClickedCallback(cb); +} - if (edit_mode) +void LLPanelPickInfo::processParcelInfo(const LLParcelData& parcel_data) +{ + // HACK: Flag 0x2 == adult region, + // Flag 0x1 == mature region, otherwise assume PG + std::string rating_icon = "icon_event.tga"; + if (parcel_data.flags & 0x2) { - LLUICtrlFactory::getInstance()->buildPanel(this, XML_PANEL_EDIT_PICK); + rating_icon = "icon_event_adult.tga"; } - else + else if (parcel_data.flags & 0x1) { - LLUICtrlFactory::getInstance()->buildPanel(this, XML_PANEL_PICK_INFO); + rating_icon = "icon_event_mature.tga"; } - //*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); + childSetValue("maturity", rating_icon); - updateButtons(); + //*NOTE we don't removeObserver(...) ourselves cause LLRemoveParcelProcessor does it for us } -void LLPanelPick::onPickChanged(LLUICtrl* ctrl) +void LLPanelPickInfo::setEditPickCallback(const commit_callback_t& cb) { - if(mLocationChanged) - { - // Pick was enabled in onClickSet - return; - } + getChild<LLButton>("edit_btn")->setClickedCallback(cb); +} - if( mSnapshotCtrl->isDirty() - || getChild<LLLineEditor>("pick_name")->isDirty() - || getChild<LLTextEditor>("pick_desc")->isDirty() ) +// PROTECTED AREA + +void LLPanelPickInfo::resetControls() +{ + if(getAvatarId() == gAgent.getID()) { - enableSaveButton(TRUE); + childSetEnabled("edit_btn", TRUE); + childSetVisible("edit_btn", TRUE); } else { - enableSaveButton(FALSE); + childSetEnabled("edit_btn", FALSE); + childSetVisible("edit_btn", FALSE); } } -////////////////////////////////////////////////////////////////////////// -// PROTECTED AREA -////////////////////////////////////////////////////////////////////////// +void LLPanelPickInfo::resetData() +{ + setPickName(LLStringUtil::null); + setPickDesc(LLStringUtil::null); + setPickLocation(LLStringUtil::null); + setPickId(LLUUID::null); + setSnapshotId(LLUUID::null); + mPosGlobal.clearVec(); + childSetValue("maturity", LLStringUtil::null); +} -//static -std::string LLPanelPick::createLocationText(const std::string& owner_name, const std::string& original_name, - const std::string& sim_name, const LLVector3d& pos_global) +// static +std::string LLPanelPickInfo::createLocationText(const std::string& owner_name, const std::string& original_name, const std::string& sim_name, const LLVector3d& pos_global) { std::string location_text; location_text.append(owner_name); @@ -354,23 +250,23 @@ std::string LLPanelPick::createLocationText(const std::string& owner_name, const return location_text; } -void LLPanelPick::setPickName(std::string name) +void LLPanelPickInfo::setSnapshotId(const LLUUID& id) +{ + mSnapshotCtrl->setImageAssetID(id); + mSnapshotCtrl->setValid(TRUE); +} + +void LLPanelPickInfo::setPickName(const std::string& name) { childSetValue(XML_NAME, name); - - //preserving non-wrapped text for info/edit modes switching - mName = name; } -void LLPanelPick::setPickDesc(std::string desc) +void LLPanelPickInfo::setPickDesc(const std::string& desc) { childSetValue(XML_DESC, desc); - - //preserving non-wrapped text for info/edit modes switching - mDesc = desc; } -void LLPanelPick::setPickLocation(const std::string& location) +void LLPanelPickInfo::setPickLocation(const std::string& location) { childSetValue(XML_LOCATION, location); @@ -378,208 +274,253 @@ void LLPanelPick::setPickLocation(const std::string& location) mLocation = location; } -std::string LLPanelPick::getPickName() +void LLPanelPickInfo::onClickMap() { - return childGetValue(XML_NAME).asString(); + LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal()); + LLFloaterReg::showInstance("world_map", "center"); } -std::string LLPanelPick::getPickDesc() +void LLPanelPickInfo::onClickTeleport() { - return childGetValue(XML_DESC).asString(); + if (!getPosGlobal().isExactlyZero()) + { + gAgent.teleportViaLocation(getPosGlobal()); + LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal()); + } } -std::string LLPanelPick::getPickLocation() +void LLPanelPickInfo::onClickBack() { - return childGetValue(XML_LOCATION).asString(); + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this); } -void LLPanelPick::sendUpdate() +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +//static +LLPanelPickEdit* LLPanelPickEdit::create() { - LLPickData pick_data; + LLPanelPickEdit* panel = new LLPanelPickEdit(); + LLUICtrlFactory::getInstance()->buildPanel(panel, XML_PANEL_EDIT_PICK); + return panel; +} - // 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(); +LLPanelPickEdit::LLPanelPickEdit() + : LLPanelPickInfo() + , mLocationChanged(false) + , mNeedData(true) +{ +} - pick_data.agent_id = gAgent.getID(); - pick_data.session_id = gAgent.getSessionID(); - pick_data.pick_id = mPickId; - pick_data.creator_id = gAgentID; +LLPanelPickEdit::~LLPanelPickEdit() +{ +} - //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; +void LLPanelPickEdit::onOpen(const LLSD& key) +{ + LLUUID pick_id = key["pick_id"]; + mNeedData = true; - mDataReceived = FALSE; - LLAvatarPropertiesProcessor::instance().addObserver(gAgentID, this); + // creating new Pick + if(pick_id.isNull()) + { + setAvatarId(gAgent.getID()); - LLAvatarPropertiesProcessor::instance().sendPickInfoUpdate(&pick_data); -} + resetData(); + resetControls(); + setPosGlobal(gAgent.getPositionGlobal()); -//----------------------------------------- -// "PICK INFO" (VIEW MODE) BUTTON HANDLERS -//----------------------------------------- + LLUUID parcel_id = LLUUID::null, snapshot_id = LLUUID::null; + std::string pick_name, pick_desc; -//static -void LLPanelPick::onClickEdit() -{ - if (mEditMode) return; - if (!mDataReceived) return; - setEditMode(TRUE); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if(parcel) + { + parcel_id = parcel->getID(); + pick_name = parcel->getName(); + pick_desc = parcel->getDesc(); + snapshot_id = parcel->getSnapshotID(); + } + + setParcelID(parcel_id); + childSetValue("pick_name", pick_name); + childSetValue("pick_desc", pick_desc); + setSnapshotId(snapshot_id); + setPickLocation(createLocationText(LLStringUtil::null, SET_LOCATION_NOTICE, + pick_name, getPosGlobal())); + + enableSaveButton(true); + } + // editing existing pick + else + { + LLPanelPickInfo::onOpen(key); + + enableSaveButton(false); + } + + resetDirty(); } -//static -void LLPanelPick::onClickTeleport() +void LLPanelPickEdit::setPickData(const LLPickData* pick_data) { - teleport(mPosGlobal); + if(!pick_data) + { + return; + } + + mNeedData = false; + + setParcelID(pick_data->parcel_id); + childSetValue("pick_name", pick_data->name); + childSetValue("pick_desc", pick_data->desc); + setSnapshotId(pick_data->snapshot_id); + setPickLocation(createLocationText(pick_data->user_name, pick_data->original_name, /*pick_data->sim_name,*/ + pick_data->name, pick_data->pos_global)); } -//static -void LLPanelPick::onClickMap() +BOOL LLPanelPickEdit::postBuild() { - showOnMap(mPosGlobal); -} + LLPanelPickInfo::postBuild(); + mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1)); + mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelPickEdit::childSetVisible, this, "edit_icon", true)); + mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelPickEdit::childSetVisible, this, "edit_icon", false)); -//----------------------------------------- -// "EDIT PICK" (EDIT MODE) BUTTON HANDLERS -//----------------------------------------- + LLLineEditor* line_edit = getChild<LLLineEditor>("pick_name"); + line_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1), NULL); -//static -void LLPanelPick::onClickCancel() + LLTextEditor* text_edit = getChild<LLTextEditor>("pick_desc"); + text_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1)); + + childSetAction(XML_BTN_SAVE, boost::bind(&LLPanelPickEdit::onClickSave, this)); + childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelPickEdit::onClickSetLocation, this)); + + return TRUE; +} + +void LLPanelPickEdit::setSaveCallback(const commit_callback_t& cb) { - if (!mEditMode) return; - - if (mIsPickNew) - { - mBackCb(this, LLSD()); - return; - } + getChild<LLButton>("save_changes_btn")->setClickedCallback(cb); +} - LLUUID pick_id = mPickId; - LLUUID creator_id = mCreatorId; - reset(); - init(creator_id, pick_id); +void LLPanelPickEdit::setCancelCallback(const commit_callback_t& cb) +{ + getChild<LLButton>("cancel_btn")->setClickedCallback(cb); } -// static -void LLPanelPick::onClickSet() +void LLPanelPickEdit::resetDirty() { - if (!mEditMode) return; - if (!mIsPickNew && !mDataReceived) return; + LLPanelPickInfo::resetDirty(); - // Save location for later. - mPosGlobal = gAgent.getPositionGlobal(); + getChild<LLLineEditor>("pick_name")->resetDirty(); + getChild<LLTextEditor>("pick_desc")->resetDirty(); + mSnapshotCtrl->resetDirty(); + mLocationChanged = false; +} - LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - if (parcel) +BOOL LLPanelPickEdit::isDirty() const +{ + if( LLPanelPickInfo::isDirty() + || mLocationChanged + || mSnapshotCtrl->isDirty() + || getChild<LLLineEditor>("pick_name")->isDirty() + || getChild<LLTextEditor>("pick_desc")->isDirty()) { - mParcelId = parcel->getID(); - mSimName = parcel->getName(); + return TRUE; } - setPickLocation(createLocationText(std::string(""), SET_LOCATION_NOTICE, mSimName, mPosGlobal)); - - mLocationChanged = true; - enableSaveButton(TRUE); + return FALSE; } -// static -void LLPanelPick::onClickSave() +// PROTECTED AREA + +void LLPanelPickEdit::sendUpdate() { - if (!mEditMode) return; - if (!mIsPickNew && !mDataReceived) return; + LLPickData pick_data; - sendUpdate(); - - if (mIsPickNew) + // 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 (getPickId().isNull()) { - mBackCb(this, LLSD()); - return; + getPickId().generate(); } - setEditMode(FALSE); + pick_data.agent_id = gAgent.getID(); + pick_data.session_id = gAgent.getSessionID(); + pick_data.pick_id = getPickId(); + pick_data.creator_id = gAgent.getID();; + + //legacy var need to be deleted + pick_data.top_pick = FALSE; + pick_data.parcel_id = mParcelId; + pick_data.name = childGetValue(XML_NAME).asString(); + pick_data.desc = childGetValue(XML_DESC).asString(); + pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID(); + pick_data.pos_global = getPosGlobal(); + pick_data.sort_order = 0; + pick_data.enabled = TRUE; + + LLAvatarPropertiesProcessor::instance().sendPickInfoUpdate(&pick_data); } -void LLPanelPick::updateButtons() +void LLPanelPickEdit::onPickChanged(LLUICtrl* ctrl) { - - // on Pick Info panel (for non-Agent picks) edit_btn should be invisible - if (mEditMode) + if(isDirty()) { - childSetLabelArg(XML_BTN_SAVE, SAVE_BTN_LABEL, std::string("Changes")); + enableSaveButton(true); } - else + else { - if (mCreatorId != gAgentID) - { - childSetEnabled("edit_btn", FALSE); - childSetVisible("edit_btn", FALSE); - } - else - { - childSetEnabled("edit_btn", TRUE); - childSetVisible("edit_btn", TRUE); - } + enableSaveButton(false); } } -void LLPanelPick::setExitCallback(commit_callback_t cb) +void LLPanelPickEdit::resetData() { - mBackCb = cb; - LLButton* button = findChild<LLButton>("back_btn"); - if (button) button->setClickedCallback(mBackCb); + LLPanelPickInfo::resetData(); + mLocationChanged = false; } -//static -void LLPanelPick::teleport(const LLVector3d& position) +void LLPanelPickEdit::enableSaveButton(bool enable) { - if (!position.isExactlyZero()) - { - gAgent.teleportViaLocation(position); - LLFloaterWorldMap::getInstance()->trackLocation(position); - } + childSetEnabled(XML_BTN_SAVE, enable); } -//static -void LLPanelPick::showOnMap(const LLVector3d& position) +void LLPanelPickEdit::onClickSetLocation() { - LLFloaterWorldMap::getInstance()->trackLocation(position); - LLFloaterReg::showInstance("world_map", "center"); + // Save location for later use. + setPosGlobal(gAgent.getPositionGlobal()); + + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (parcel) + { + mParcelId = parcel->getID(); + mSimName = parcel->getName(); + } + setPickLocation(createLocationText( + LLStringUtil::null, SET_LOCATION_NOTICE, mSimName, getPosGlobal())); + + mLocationChanged = true; + enableSaveButton(TRUE); } -void LLPanelPick::processParcelInfo(const LLParcelData& parcel_data) +void LLPanelPickEdit::onClickSave() { - if (mEditMode) return; + sendUpdate(); - // 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); + mLocationChanged = false; - //*NOTE we don't removeObserver(...) ourselves cause LLRemoveParcelProcessor does it for us + LLSD params; + params["action"] = "save_new_pick"; + notifyParent(params); } -void LLPanelPick::enableSaveButton(bool enable) +void LLPanelPickEdit::processProperties(void* data, EAvatarProcessorType type) { - if(!mEditMode) + if(mNeedData) { - return; + LLPanelPickInfo::processProperties(data, type); } - childSetEnabled(XML_BTN_SAVE, enable); } diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h index 82cba72bc4..c5b13c69ea 100644 --- a/indra/newview/llpanelpick.h +++ b/indra/newview/llpanelpick.h @@ -39,53 +39,46 @@ #include "llpanel.h" #include "llremoteparcelrequest.h" +#include "llavatarpropertiesprocessor.h" class LLTextureCtrl; class LLMessageSystem; class LLAvatarPropertiesObserver; -class LLPanelPick : public LLPanel, public LLAvatarPropertiesObserver, LLRemoteParcelInfoObserver +/** + * Panel for displaying Pick Information - snapshot, name, description, etc. + */ +class LLPanelPickInfo : public LLPanel, public LLAvatarPropertiesObserver, LLRemoteParcelInfoObserver { - LOG_CLASS(LLPanelPick); + LOG_CLASS(LLPanelPickInfo); public: - LLPanelPick(BOOL edit_mode = FALSE); - /*virtual*/ ~LLPanelPick(); - - // switches the panel to the VIEW mode and resets controls - void reset(); + + // Creates new panel + static LLPanelPickInfo* create(); - /*virtual*/ BOOL postBuild(); + virtual ~LLPanelPickInfo(); - // Prepares a new pick, including creating an id, giving a sane - // initial position, etc (saved on clicking Save Pick button - onClickSave callback). - void prepareNewPick(); - void prepareNewPick(const LLVector3d pos_global, - const std::string& name, - const std::string& desc, - const LLUUID& snapshot_id, - const LLUUID& parcel_id); + /** + * Initializes panel properties + * + * By default Pick will be created for current Agent location. + * Use setPickData to change Pick properties. + */ + /*virtual*/ void onOpen(const LLSD& key); - //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*/ BOOL postBuild(); /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); - // switches the panel to either View or Edit mode - void setEditMode(BOOL edit_mode); - - void onPickChanged(LLUICtrl* ctrl); - - // 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); + /** + * Sets "Back" button click callback + */ + virtual void setExitCallback(const commit_callback_t& cb); - static void teleport(const LLVector3d& position); - static void showOnMap(const LLVector3d& position); + /** + * Sets "Edit" button click callback + */ + virtual void setEditPickCallback(const commit_callback_t& cb); //This stuff we got from LLRemoteParcelObserver, in the last two we intentionally do nothing /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); @@ -94,63 +87,154 @@ public: protected: + LLPanelPickInfo(); + + /** + * Resets Pick information + */ + virtual void resetData(); + + /** + * Resets UI controls (visibility, values) + */ + virtual void resetControls(); + /** * "Location text" is actually the owner name, the original * name that owner gave the parcel, and the location. */ - static std::string createLocationText(const std::string& owner_name, const std::string& original_name, - const std::string& sim_name, const LLVector3d& pos_global); + static std::string createLocationText( + const std::string& owner_name, + const std::string& original_name, + const std::string& sim_name, + const LLVector3d& pos_global); + + virtual void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; } + virtual LLUUID& getAvatarId() { return mAvatarId; } + + /** + * Sets snapshot id. + * + * Will mark snapshot control as valid if id is not null. + * Will mark snapshot control as invalid if id is null. If null id is a valid value, + * you have to manually mark snapshot is valid. + */ + virtual void setSnapshotId(const LLUUID& id); + + virtual void setPickId(const LLUUID& id) { mPickId = id; } + virtual LLUUID& getPickId() { return mPickId; } + + virtual void setPickName(const std::string& name); + + virtual void setPickDesc(const std::string& desc); + + virtual void setPickLocation(const std::string& location); + + virtual void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; } + virtual LLVector3d& getPosGlobal() { return mPosGlobal; } + + /** + * Callback for "Map" button, opens Map + */ + void onClickMap(); - void setPickName(std::string name); - void setPickDesc(std::string desc); - void setPickLocation(const std::string& location); + /** + * Callback for "Teleport" button, teleports user to Pick location. + */ + void onClickTeleport(); - std::string getPickName(); - std::string getPickDesc(); - std::string getPickLocation(); + void onClickBack(); - void sendUpdate(); - void requestData(); +protected: - void init(LLPickData *pick_data); + LLTextureCtrl* mSnapshotCtrl; - void updateButtons(); + LLUUID mAvatarId; + LLVector3d mPosGlobal; + LLUUID mParcelId; + LLUUID mPickId; + std::string mSimName; + std::string mLocation; +}; - //----------------------------------------- - // "PICK INFO" (VIEW MODE) BUTTON HANDLERS - //----------------------------------------- - void onClickEdit(); - void onClickTeleport(); - void onClickMap(); +/** + * Panel for creating/editing Pick. + */ +class LLPanelPickEdit : public LLPanelPickInfo +{ + LOG_CLASS(LLPanelPickEdit); +public: - //----------------------------------------- - // "EDIT PICK" (EDIT MODE) BUTTON HANDLERS - //----------------------------------------- - void onClickSet(); - void onClickSave(); - void onClickCancel(); + /** + * Creates new panel + */ + static LLPanelPickEdit* create(); - void enableSaveButton(bool enable); + /*virtual*/ ~LLPanelPickEdit(); + + /*virtual*/ void onOpen(const LLSD& key); + + virtual void setPickData(const LLPickData* pick_data); + + /*virtual*/ BOOL postBuild(); + + /** + * Sets "Save" button click callback + */ + virtual void setSaveCallback(const commit_callback_t& cb); + + /** + * Sets "Cancel" button click callback + */ + virtual void setCancelCallback(const commit_callback_t& cb); + + /** + * Resets panel and all cantrols to unedited state + */ + /*virtual*/ void resetDirty(); + + /** + * Returns true if any of Pick properties was changed by user. + */ + /*virtual*/ BOOL isDirty() const; + + /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); protected: - BOOL mEditMode; - LLTextureCtrl* mSnapshotCtrl; - BOOL mDataReceived; - bool mIsPickNew; - LLUUID mPickId; - LLUUID mCreatorId; - LLVector3d mPosGlobal; - LLUUID mParcelId; - std::string mSimName; + LLPanelPickEdit(); - //These strings are used to keep non-wrapped text - std::string mName; - std::string mDesc; - std::string mLocation; + /** + * Sends Pick properties to server. + */ + void sendUpdate(); + + /** + * Callback for Pick snapshot, name and description changed event. + */ + void onPickChanged(LLUICtrl* ctrl); + + /*virtual*/ void resetData(); + + /** + * Enables/disables "Save" button + */ + void enableSaveButton(bool enable); + + /** + * Callback for "Set Location" button click + */ + void onClickSetLocation(); + + /** + * Callback for "Save" button click + */ + void onClickSave(); + +protected: - commit_callback_t mBackCb; bool mLocationChanged; + bool mNeedData; }; #endif // LL_LLPANELPICK_H diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index 979e9618da..073da5cc06 100644 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -35,6 +35,8 @@ #include "llagent.h" #include "llavatarconstants.h" #include "llflatlistview.h" +#include "llfloaterreg.h" +#include "llfloaterworldmap.h" #include "lltexturectrl.h" #include "llviewergenericmessage.h" // send_generic_message #include "llmenugl.h" @@ -69,6 +71,8 @@ LLPanelPicks::LLPanelPicks() mProfilePanel(NULL), mPickPanel(NULL), mPicksList(NULL) + , mPanelPickInfo(NULL) + , mPanelPickEdit(NULL) { } @@ -197,7 +201,7 @@ void LLPanelPicks::onOpen(const LLSD& key) mPopupMenu->setItemVisible("pick_separator", TRUE); } - if(getAvatarId() != key.asUUID()) + if(getAvatarId() != id) { mPicksList->goToTop(); } @@ -247,7 +251,13 @@ void LLPanelPicks::onClickTeleport() { LLPickItem* pick_item = getSelectedPickItem(); if (!pick_item) return; - LLPanelPick::teleport(pick_item->getPosGlobal()); + + LLVector3d pos = pick_item->getPosGlobal(); + if (!pos.isExactlyZero()) + { + gAgent.teleportViaLocation(pos); + LLFloaterWorldMap::getInstance()->trackLocation(pos); + } } //static @@ -255,7 +265,9 @@ void LLPanelPicks::onClickMap() { LLPickItem* pick_item = getSelectedPickItem(); if (!pick_item) return; - LLPanelPick::showOnMap(pick_item->getPosGlobal()); + + LLFloaterWorldMap::getInstance()->trackLocation(pick_item->getPosGlobal()); + LLFloaterReg::showInstance("world_map", "center"); } @@ -308,19 +320,18 @@ void LLPanelPicks::setProfilePanel(LLPanelProfile* profile_panel) void LLPanelPicks::buildPickPanel() { - if (mPickPanel == NULL) - { - mPickPanel = new LLPanelPick(); - mPickPanel->setExitCallback(boost::bind(&LLPanelPicks::onClickBack, this)); - } +// if (mPickPanel == NULL) +// { +// mPickPanel = new LLPanelPick(); +// mPickPanel->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, NULL)); +// } } void LLPanelPicks::onClickNew() { - buildPickPanel(); - mPickPanel->setEditMode(TRUE); - mPickPanel->prepareNewPick(); - getProfilePanel()->togglePanel(mPickPanel); + createPickEditPanel(); + + getProfilePanel()->openPanel(mPanelPickEdit, LLSD()); } void LLPanelPicks::onClickInfo() @@ -328,28 +339,98 @@ void LLPanelPicks::onClickInfo() LLSD selected_value = mPicksList->getSelectedValue(); if (selected_value.isUndefined()) return; - buildPickPanel(); - mPickPanel->reset(); - mPickPanel->init(selected_value[PICK_CREATOR_ID], selected_value[PICK_ID]); - getProfilePanel()->togglePanel(mPickPanel); + LLPickItem* pick = (LLPickItem*)mPicksList->getSelectedItem(); + + createPickInfoPanel(); + + LLSD params; + params["pick_id"] = pick->getPickId(); + params["avatar_id"] = pick->getCreatorId(); + params["snapshot_id"] = pick->getSnapshotId(); + params["pick_name"] = pick->getPickName(); + params["pick_desc"] = pick->getPickDesc(); + + getProfilePanel()->openPanel(mPanelPickInfo, params); } -void LLPanelPicks::onClickBack() +void LLPanelPicks::onPanelPickClose(LLPanel* panel) { - getProfilePanel()->togglePanel(mPickPanel); + panel->setVisible(FALSE); } -void LLPanelPicks::onClickMenuEdit() +void LLPanelPicks::createPickInfoPanel() +{ + if(!mPanelPickInfo) + { + mPanelPickInfo = LLPanelPickInfo::create(); + mPanelPickInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickInfo)); + mPanelPickInfo->setEditPickCallback(boost::bind(&LLPanelPicks::onPanelPickEdit, this)); + mPanelPickInfo->setVisible(FALSE); + } +} + +void LLPanelPicks::createPickEditPanel() +{ + if(!mPanelPickEdit) + { + mPanelPickEdit = LLPanelPickEdit::create(); + mPanelPickEdit->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit)); + mPanelPickEdit->setSaveCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit)); + mPanelPickEdit->setCancelCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit)); + mPanelPickEdit->setVisible(FALSE); + } +} + +// void LLPanelPicks::openPickEditPanel(LLPickItem* pick) +// { +// if(!pick) +// { +// return; +// } +// } + +// void LLPanelPicks::openPickInfoPanel(LLPickItem* pick) +// { +// if(!mPanelPickInfo) +// { +// mPanelPickInfo = LLPanelPickInfo::create(); +// mPanelPickInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickInfo)); +// mPanelPickInfo->setEditPickCallback(boost::bind(&LLPanelPicks::onPanelPickEdit, this)); +// mPanelPickInfo->setVisible(FALSE); +// } +// +// LLSD params; +// params["pick_id"] = pick->getPickId(); +// params["avatar_id"] = pick->getCreatorId(); +// params["snapshot_id"] = pick->getSnapshotId(); +// params["pick_name"] = pick->getPickName(); +// params["pick_desc"] = pick->getPickDesc(); +// +// getProfilePanel()->openPanel(mPanelPickInfo, params); +// } + +void LLPanelPicks::onPanelPickEdit() { - //*TODO, refactor - most of that is similar to onClickInfo LLSD selected_value = mPicksList->getSelectedValue(); if (selected_value.isUndefined()) return; - buildPickPanel(); - mPickPanel->reset(); - mPickPanel->init(selected_value[PICK_CREATOR_ID], selected_value[PICK_ID]); - mPickPanel->setEditMode(TRUE); - getProfilePanel()->togglePanel(mPickPanel); + LLPickItem* pick = dynamic_cast<LLPickItem*>(mPicksList->getSelectedItem()); + + createPickEditPanel(); + + LLSD params; + params["pick_id"] = pick->getPickId(); + params["avatar_id"] = pick->getCreatorId(); + params["snapshot_id"] = pick->getSnapshotId(); + params["pick_name"] = pick->getPickName(); + params["pick_desc"] = pick->getPickDesc(); + + getProfilePanel()->openPanel(mPanelPickEdit, params); +} + +void LLPanelPicks::onClickMenuEdit() +{ + onPanelPickEdit(); } inline LLPanelProfile* LLPanelPicks::getProfilePanel() @@ -391,6 +472,10 @@ void LLPickItem::init(LLPickData* pick_data) setPickDesc(pick_data->desc); setSnapshotId(pick_data->snapshot_id); mPosGlobal = pick_data->pos_global; + mSimName = pick_data->sim_name; + mPickDescription = pick_data->desc; + mUserName = pick_data->user_name; + mOriginalName = pick_data->original_name; LLTextureCtrl* picture = getChild<LLTextureCtrl>("picture"); picture->setImageAssetID(pick_data->snapshot_id); @@ -445,38 +530,32 @@ const std::string LLPickItem::getDescription() void LLPickItem::update() { - mNeedData = true; + setNeedData(true); LLAvatarPropertiesProcessor::instance().sendPickInfoRequest(mCreatorID, mPickID); - mNeedData = false; } void LLPickItem::processProperties(void *data, EAvatarProcessorType type) { - if (APT_PICK_INFO != type) return; - if (!data) return; + if (APT_PICK_INFO != type) + { + return; + } LLPickData* pick_data = static_cast<LLPickData *>(data); - if (!pick_data) return; - if (mPickID != pick_data->pick_id) return; + if (!pick_data || mPickID != pick_data->pick_id) + { + return; + } init(pick_data); + setNeedData(false); LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this); } -// virtual -void LLPanelPicks::onClosePanel() -{ - // Toggle off Pick Info panel if it is visible. - if(mPickPanel && mPickPanel->getVisible()) - { - getProfilePanel()->togglePanel(mPickPanel); - } -} - BOOL LLPickItem::postBuild() { - setMouseEnterCallback(boost::bind(&LLPanelPick::childSetVisible, this, "hovered_icon", true)); - setMouseLeaveCallback(boost::bind(&LLPanelPick::childSetVisible, this, "hovered_icon", false)); + setMouseEnterCallback(boost::bind(&LLPanelPickInfo::childSetVisible, this, "hovered_icon", true)); + setMouseLeaveCallback(boost::bind(&LLPanelPickInfo::childSetVisible, this, "hovered_icon", false)); return TRUE; } diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h index 18c571c735..6264a19318 100644 --- a/indra/newview/llpanelpicks.h +++ b/indra/newview/llpanelpicks.h @@ -44,11 +44,12 @@ class LLPanelProfile; class LLMessageSystem; class LLVector3d; class LLPanelProfileTab; -class LLPanelPick; class LLAgent; class LLMenuGL; class LLPickItem; class LLFlatListView; +class LLPanelPickInfo; +class LLPanelPickEdit; class LLPanelPicks : public LLPanelProfileTab @@ -74,11 +75,6 @@ public: // 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 onClosePanel(); - private: void onClickDelete(); void onClickTeleport(); @@ -89,7 +85,8 @@ private: //------------------------------------------------ void onClickNew(); void onClickInfo(); - void onClickBack(); + void onPanelPickClose(LLPanel* panel); + void onPanelPickEdit(); void onClickMenuEdit(); void buildPickPanel(); @@ -104,10 +101,17 @@ private: LLPanelProfile* getProfilePanel(); + void createPickInfoPanel(); + void createPickEditPanel(); +// void openPickEditPanel(LLPickItem* pick); +// void openPickInfoPanel(LLPickItem* pick); + LLMenuGL* mPopupMenu; LLPanelProfile* mProfilePanel; - LLPanelPick* mPickPanel; + LLPanelPickInfo* mPickPanel; LLFlatListView* mPicksList; + LLPanelPickInfo* mPanelPickInfo; + LLPanelPickEdit* mPanelPickEdit; }; class LLPickItem : public LLPanel, public LLAvatarPropertiesObserver @@ -144,6 +148,14 @@ public: const std::string getDescription(); + const std::string& getSimName() { return mSimName; } + + const std::string& getUserName() { return mUserName; } + + const std::string& getOriginalName() { return mOriginalName; } + + const std::string& getPickDesc() { return mPickDescription; } + /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); void update(); @@ -165,6 +177,10 @@ protected: bool mNeedData; std::string mPickName; + std::string mUserName; + std::string mOriginalName; + std::string mPickDescription; + std::string mSimName; }; #endif // LL_LLPANELPICKS_H diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index 8ed22ebbde..6d1a5fb184 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -909,7 +909,7 @@ void LLPanelPlaceInfo::createLandmark(const LLUUID& folder_id) folder_id.notNull() ? folder_id : gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK)); } -void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPick* pick_panel) +void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel) { std::string name = mParcelName->getText(); if (name.empty()) @@ -917,11 +917,13 @@ void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPick* pic name = mRegionName->getText(); } - pick_panel->prepareNewPick(pos_global, - name, - mDescEditor->getText(), - mSnapshotCtrl->getImageAssetID(), - mParcelID); + LLPickData data; + data.pos_global = pos_global; + data.name = name; + data.desc = mDescEditor->getText(); + data.snapshot_id = mSnapshotCtrl->getImageAssetID(); + data.parcel_id = mParcelID; + pick_panel->setPickData(&data); } // virtual diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h index 3e8344ff12..06fee2224e 100644 --- a/indra/newview/llpanelplaceinfo.h +++ b/indra/newview/llpanelplaceinfo.h @@ -45,7 +45,7 @@ class LLButton; class LLComboBox; class LLInventoryItem; class LLLineEditor; -class LLPanelPick; +class LLPanelPickEdit; class LLParcel; class LLIconCtrl; class LLTextBox; @@ -89,7 +89,7 @@ public: // Create a pick for the location specified // by global_pos. - void createPick(const LLVector3d& pos_global, LLPanelPick* pick_panel); + void createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel); BOOL isMediaPanelVisible(); void toggleMediaPanel(BOOL visible); diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index d415b17538..f30bb1a0a6 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -635,21 +635,39 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param) if (mPickPanel == NULL) { - mPickPanel = new LLPanelPick(); + mPickPanel = LLPanelPickEdit::create(); addChild(mPickPanel); mPickPanel->setExitCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE)); + mPickPanel->setCancelCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE)); + mPickPanel->setSaveCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE)); } togglePickPanel(TRUE); + mPickPanel->onOpen(LLSD()); + mPlaceInfo->createPick(mPosGlobal, mPickPanel); LLRect rect = getRect(); mPickPanel->reshape(rect.getWidth(), rect.getHeight()); mPickPanel->setRect(rect); - mPickPanel->setEditMode(TRUE); - - mPlaceInfo->createPick(mPosGlobal, mPickPanel); } + else if (item == "add_to_favbar") + { + if ( mItem.notNull() ) + { + LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE); + if ( favorites_id.notNull() ) + { + copy_inventory_item(gAgent.getID(), + mItem->getPermissions().getOwner(), + mItem->getUUID(), + favorites_id, + std::string(), + LLPointer<LLInventoryCallback>(NULL)); + llinfos << "Copied inventory item #" << mItem->getUUID() << " to favorites." << llendl; + } + } + } } void LLPanelPlaces::onBackButtonClicked() diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index ce20ffdc91..70c50b2058 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -37,7 +37,7 @@ class LLInventoryItem; class LLFilterEditor; class LLLandmark; -class LLPanelPick; +class LLPanelPickEdit; class LLPanelPlaceInfo; class LLPanelPlacesTab; class LLParcelSelection; @@ -91,7 +91,7 @@ private: LLPanelPlacesTab* mActivePanel; LLTabContainer* mTabContainer; LLPanelPlaceInfo* mPlaceInfo; - LLPanelPick* mPickPanel; + LLPanelPickEdit* mPickPanel; LLToggleableMenu* mPlaceMenu; LLToggleableMenu* mLandmarkMenu; diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index cda7942c1d..08d2baf6cd 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -117,25 +117,21 @@ void LLPanelProfile::onOpen(const LLSD& key) void LLPanelProfile::togglePanel(LLPanel* panel) { // TRUE - we need to open/expand "panel" - bool expand = getChildList()->back() != panel; // mTabCtrl->getVisible(); + bool expand = getChildList()->front() != 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); + addChild(panel); } else { - sendChildToBack(panel); + sendChildToFront(panel); } + panel->setVisible(TRUE); + 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()); @@ -143,13 +139,12 @@ void LLPanelProfile::togglePanel(LLPanel* panel) } else { - this->setAllChildrenVisible(TRUE); panel->setVisible(FALSE); if (panel->getParent() == this) { removeChild(panel); } - sendChildToBack(getTabCtrl()); + getTabCtrl()->getCurrentPanel()->onOpen(getAvatarId()); } } @@ -174,3 +169,34 @@ void LLPanelProfile::setAllChildrenVisible(BOOL visible) } } +void LLPanelProfile::openPanel(LLPanel* panel, const LLSD& params) +{ + if (panel->getParent() != this) + { + addChild(panel); + } + else + { + sendChildToFront(panel); + } + + panel->setVisible(TRUE); + + panel->onOpen(params); + + 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); +} + +void LLPanelProfile::notifyParent(const LLSD& info) +{ + // lets update Picks list after Pick was saved + if("save_new_pick" == info["action"]) + { + onOpen(info); + return; + } + LLPanel::notifyParent(info); +} diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h index bb893f257a..e0b827c986 100644 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h @@ -53,6 +53,10 @@ public: virtual void togglePanel(LLPanel*); + virtual void openPanel(LLPanel* panel, const LLSD& params); + + void notifyParent(const LLSD& info); + protected: LLPanelProfile(); diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index e1e3fe4677..207ed723b2 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -47,6 +47,10 @@ #include "lllandmarkactions.h" #include "llclipboard.h" +// Maximum number of items that can be added to a list in one pass. +// Used to limit time spent for items list update per frame. +static const U32 ADD_LIMIT = 50; + class LLTeleportHistoryFlatItem : public LLPanel { public: @@ -56,6 +60,7 @@ public: virtual BOOL postBuild(); S32 getIndex() { return mIndex; } + const std::string& getRegionName() { return mRegionName;} /*virtual*/ void setValue(const LLSD& value); @@ -211,11 +216,13 @@ void LLTeleportHistoryPanel::ContextMenu::onCopy() LLTeleportHistoryPanel::LLTeleportHistoryPanel() : LLPanelPlacesTab(), mFilterSubString(LLStringUtil::null), + mDirty(true), + mCurrentItem(0), mTeleportHistory(NULL), mHistoryAccordion(NULL), - mStarButton(NULL), mAccordionTabMenu(NULL), - mLastSelectedScrollList(NULL) + mLastSelectedFlatlList(NULL), + mLastSelectedItemIndex(-1) { LLUICtrlFactory::getInstance()->buildPanel(this, "panel_teleport_history.xml"); } @@ -230,7 +237,7 @@ BOOL LLTeleportHistoryPanel::postBuild() mTeleportHistory = LLTeleportHistoryStorage::getInstance(); if (mTeleportHistory) { - mTeleportHistory->setHistoryChangedCallback(boost::bind(&LLTeleportHistoryPanel::showTeleportHistory, this)); + mTeleportHistory->setHistoryChangedCallback(boost::bind(&LLTeleportHistoryPanel::onTeleportHistoryChange, this)); } mHistoryAccordion = getChild<LLAccordionCtrl>("history_accordion"); @@ -277,13 +284,19 @@ BOOL LLTeleportHistoryPanel::postBuild() if(gear_menu) mGearMenuHandle = gear_menu->getHandle(); - mStarButton = getChild<LLButton>("star_btn"); - mStarButton->setCommitCallback(boost::bind(&LLTeleportHistoryPanel::onStarButtonCommit, this)); - return TRUE; } // virtual +void LLTeleportHistoryPanel::draw() +{ + if (mDirty) + refresh(); + + LLPanelPlacesTab::draw(); +} + +// virtual void LLTeleportHistoryPanel::onSearchEdit(const std::string& string) { if (mFilterSubString != string) @@ -296,10 +309,10 @@ void LLTeleportHistoryPanel::onSearchEdit(const std::string& string) // virtual void LLTeleportHistoryPanel::onShowOnMap() { - if (!mLastSelectedScrollList) + if (!mLastSelectedFlatlList) return; - LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedScrollList->getSelectedItem()); + LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedFlatlList->getSelectedItem()); if(!itemp) return; @@ -316,10 +329,10 @@ void LLTeleportHistoryPanel::onShowOnMap() // virtual void LLTeleportHistoryPanel::onTeleport() { - if (!mLastSelectedScrollList) + if (!mLastSelectedFlatlList) return; - LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedScrollList->getSelectedItem()); + LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedFlatlList->getSelectedItem()); if(!itemp) return; @@ -357,159 +370,169 @@ void LLTeleportHistoryPanel::updateVerbs() if (!isTabVisible()) return; - if (!mLastSelectedScrollList) + if (!mLastSelectedFlatlList) { mTeleportBtn->setEnabled(false); mShowOnMapBtn->setEnabled(false); - mStarButton->setEnabled(false); - mStarButton->setToolTip(LLStringExplicit("")); return; } - LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedScrollList->getSelectedItem()); + LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedFlatlList->getSelectedItem()); mTeleportBtn->setEnabled(NULL != itemp && itemp->getIndex() < (S32)mTeleportHistory->getItems().size() - 1); mShowOnMapBtn->setEnabled(NULL != itemp); +} + +void LLTeleportHistoryPanel::getNextTab(const LLDate& item_date, S32& tab_idx, LLDate& tab_date) +{ + const U32 seconds_in_day = 24 * 60 * 60; + + S32 tabs_cnt = mItemContainers.size(); + S32 curr_year = 0, curr_month = 0, curr_day = 0; + + tab_date = LLDate::now(); + tab_date.split(&curr_year, &curr_month, &curr_day); + tab_date.fromYMDHMS(curr_year, curr_month, curr_day); // Set hour, min, and sec to 0 + tab_date.secondsSinceEpoch(tab_date.secondsSinceEpoch() + seconds_in_day); - if (NULL != itemp) + tab_idx = -1; + + while (tab_idx < tabs_cnt - 1 && item_date < tab_date) { - LLViewerInventoryItem *landmark = LLLandmarkActions::findLandmarkForGlobalPos( - mTeleportHistory->getItems()[itemp->getIndex()].mGlobalPos); + tab_idx++; - mStarButton->setEnabled(true); - if (!landmark || landmark->getUUID().isNull()) + if (tab_idx <= tabs_cnt - 4) { - mStarButton->setToggleState(true); - // Landmark can be created only for current agent positon, which is most recent (last) item in teleport history. - // mTeleportBtn is disabled only for that item. - mStarButton->setToolTip(mTeleportBtn->getEnabled() ? getString("cant_create_lm_here") : getString("create_landmark")); + tab_date.secondsSinceEpoch(tab_date.secondsSinceEpoch() - seconds_in_day); } - else + else if (tab_idx == tabs_cnt - 3) // 6 day and older, low boundary is 1 month { - mStarButton->setToggleState(false); - mStarButton->setToolTip(getString("open_landmark")); + tab_date = LLDate::now(); + tab_date.split(&curr_year, &curr_month, &curr_day); + curr_month--; + if (0 == curr_month) + { + curr_month = 12; + curr_year--; + } + tab_date.fromYMDHMS(curr_year, curr_month, curr_day); + } + else if (tab_idx == tabs_cnt - 2) // 1 month and older, low boundary is 6 months + { + tab_date = LLDate::now(); + tab_date.split(&curr_year, &curr_month, &curr_day); + if (curr_month > 6) + { + curr_month -= 6; + } + else + { + curr_month += 6; + curr_year--; + } + tab_date.fromYMDHMS(curr_year, curr_month, curr_day); + } + else // 6 months and older + { + tab_date.secondsSinceEpoch(0); } - } - else - { - mStarButton->setEnabled(false); - mStarButton->setToolTip(LLStringExplicit("")); } } -void LLTeleportHistoryPanel::showTeleportHistory() +void LLTeleportHistoryPanel::refresh() { if (!mHistoryAccordion) + { + mDirty = false; return; + } - const LLTeleportHistoryStorage::slurl_list_t& hist_items = mTeleportHistory->getItems(); - - const U32 seconds_in_day = 24 * 60 * 60; - LLDate curr_date = LLDate::now(); - - S32 curr_tab = -1; - S32 tabs_cnt = mItemContainers.size(); - S32 curr_year = 0, curr_month = 0, curr_day = 0; - - curr_date.split(&curr_year, &curr_month, &curr_day); - curr_date.fromYMDHMS(curr_year, curr_month, curr_day); // Set hour, min, and sec to 0 - curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() + seconds_in_day); + const LLTeleportHistoryStorage::slurl_list_t& items = mTeleportHistory->getItems(); + LLDate tab_boundary_date = LLDate::now(); LLFlatListView* curr_flat_view = NULL; - S32 index = hist_items.size() - 1; - - for (LLTeleportHistoryStorage::slurl_list_t::const_reverse_iterator iter = hist_items.rbegin(); - iter != hist_items.rend(); ++iter, --index) + U32 added_items = 0; + while (mCurrentItem >= 0) { - std::string landmark_title = (*iter).mTitle; + std::string landmark_title = items[mCurrentItem].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) + { + mCurrentItem--; continue; + } - if (curr_tab < tabs_cnt - 1) - { - const LLDate &date = (*iter).mDate; + const LLDate &date = items[mCurrentItem].mDate; - if (date < curr_date) - { - LLAccordionCtrlTab* tab = NULL; - while (curr_tab < tabs_cnt - 1 && date < curr_date) - { - curr_tab++; - - tab = mItemContainers.get(mItemContainers.size() - 1 - curr_tab); - tab->setVisible(false); - - if (curr_tab <= tabs_cnt - 4) - { - curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() - seconds_in_day); - } - else if (curr_tab == tabs_cnt - 3) // 6 day and older, low boundary is 1 month - { - curr_date = LLDate::now(); - curr_date.split(&curr_year, &curr_month, &curr_day); - curr_month--; - if (0 == curr_month) - { - curr_month = 12; - curr_year--; - } - curr_date.fromYMDHMS(curr_year, curr_month, curr_day); - } - else if (curr_tab == tabs_cnt - 2) // 1 month and older, low boundary is 6 months - { - curr_date = LLDate::now(); - curr_date.split(&curr_year, &curr_month, &curr_day); - if (curr_month > 6) - { - curr_month -= 6; - } - else - { - curr_month += 6; - curr_year--; - } - curr_date.fromYMDHMS(curr_year, curr_month, curr_day); - } - else // 6 months and older - { - curr_date.secondsSinceEpoch(0); - } - } + if (date < tab_boundary_date) + { + S32 tab_idx = 0; + getNextTab(date, tab_idx, tab_boundary_date); - tab->setVisible(true); + LLAccordionCtrlTab* tab = mItemContainers.get(mItemContainers.size() - 1 - tab_idx); + tab->setVisible(true); - curr_flat_view = getFlatListViewFromTab(tab); - if (curr_flat_view) - { - curr_flat_view->clear(); - } - } + curr_flat_view = getFlatListViewFromTab(tab); } if (curr_flat_view) { - curr_flat_view->addItem(new LLTeleportHistoryFlatItem(index, &mContextMenu, (*iter).mTitle)); + LLTeleportHistoryFlatItem* item = new LLTeleportHistoryFlatItem(mCurrentItem, &mContextMenu, items[mCurrentItem].mTitle); + curr_flat_view->addItem(item); + + if (mLastSelectedItemIndex == mCurrentItem) + curr_flat_view->selectItem(item, true); } - } + + mCurrentItem--; - // Hide empty tabs from current to bottom - for (curr_tab++; curr_tab < tabs_cnt; curr_tab++) - mItemContainers.get(mItemContainers.size() - 1 - curr_tab)->setVisible(false); + if (++added_items >= ADD_LIMIT) + break; + } mHistoryAccordion->arrange(); updateVerbs(); + + if (mCurrentItem < 0) + mDirty = false; +} + +void LLTeleportHistoryPanel::onTeleportHistoryChange() +{ + mLastSelectedItemIndex = -1; + showTeleportHistory(); +} + +void LLTeleportHistoryPanel::showTeleportHistory() +{ + mDirty = true; + mCurrentItem = mTeleportHistory->getItems().size() - 1; + + for (S32 n = mItemContainers.size() - 1; n >= 0; --n) + { + LLAccordionCtrlTab* tab = mItemContainers.get(n); + tab->setVisible(false); + + LLFlatListView* fv = getFlatListViewFromTab(tab); + if (fv) + fv->clear(); + } + + refresh(); } void LLTeleportHistoryPanel::handleItemSelect(LLFlatListView* selected) { - mLastSelectedScrollList = selected; + mLastSelectedFlatlList = selected; + LLTeleportHistoryFlatItem* item = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedFlatlList->getSelectedItem()); + if (item) + mLastSelectedItemIndex = item->getIndex(); S32 tabs_cnt = mItemContainers.size(); @@ -626,8 +649,6 @@ bool LLTeleportHistoryPanel::onClearTeleportHistoryDialog(const LLSD& notificati LLTeleportHistoryStorage *th = LLTeleportHistoryStorage::getInstance(); th->purgeItems(); th->save(); - - showTeleportHistory(); } return false; @@ -667,28 +688,3 @@ void LLTeleportHistoryPanel::onGearButtonClicked() LLMenuGL::showPopup(this, menu, menu_x, menu_y); } -void LLTeleportHistoryPanel::onStarButtonCommit() -{ - if (!mLastSelectedScrollList) - return; - - LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedScrollList->getSelectedItem()); - if(!itemp) - return; - - if (itemp->getIndex() < (S32)mTeleportHistory->getItems().size() - 1) - { - LLTeleportHistoryFlatItem::showPlaceInfoPanel(itemp->getIndex()); - } - else - { - LLViewerInventoryItem *landmark = LLLandmarkActions::findLandmarkForGlobalPos( - mTeleportHistory->getItems()[itemp->getIndex()].mGlobalPos); - - if (!landmark || landmark->getUUID().isNull()) - LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark")); - else - LLTeleportHistoryFlatItem::showPlaceInfoPanel(itemp->getIndex()); - } -} - diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h index f487c92836..49a97c5022 100644 --- a/indra/newview/llpanelteleporthistory.h +++ b/indra/newview/llpanelteleporthistory.h @@ -69,6 +69,8 @@ public: virtual ~LLTeleportHistoryPanel(); /*virtual*/ BOOL postBuild(); + /*virtual*/ void draw(); + /*virtual*/ void onSearchEdit(const std::string& string); /*virtual*/ void onShowOnMap(); /*virtual*/ void onTeleport(); @@ -86,17 +88,21 @@ private: void onClearTeleportHistory(); bool onClearTeleportHistoryDialog(const LLSD& notification, const LLSD& response); + void refresh(); + void getNextTab(const LLDate& item_date, S32& curr_tab, LLDate& tab_date); + void onTeleportHistoryChange(); void showTeleportHistory(); void handleItemSelect(LLFlatListView* ); LLFlatListView* getFlatListViewFromTab(LLAccordionCtrlTab *); void onGearButtonClicked(); - void onStarButtonCommit(); LLTeleportHistoryStorage* mTeleportHistory; LLAccordionCtrl* mHistoryAccordion; - LLButton * mStarButton; - LLFlatListView* mLastSelectedScrollList; + LLFlatListView* mLastSelectedFlatlList; + S32 mLastSelectedItemIndex; + bool mDirty; + S32 mCurrentItem; std::string mFilterSubString; typedef LLDynamicArray<LLAccordionCtrlTab*> item_containers_t; diff --git a/indra/newview/llplacesinventorybridge.cpp b/indra/newview/llplacesinventorybridge.cpp new file mode 100644 index 0000000000..b3b4857727 --- /dev/null +++ b/indra/newview/llplacesinventorybridge.cpp @@ -0,0 +1,200 @@ +/** + * @file llplacesinventorybridge.cpp + * @brief Implementation of the Inventory-Folder-View-Bridge classes for Places 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 "llmenugl.h" + +#include "llplacesinventorybridge.h" + +#include "llfloaterinventory.h" // for LLInventoryPanel +#include "llfolderview.h" // for FIRST_SELECTED_ITEM + + +static const std::string LANDMARKS_INVENTORY_LIST_NAME("landmarks_list"); + +bool is_landmarks_panel(const LLInventoryPanel* inv_panel) +{ + if (NULL == inv_panel) + return false; + return inv_panel->getName() == LANDMARKS_INVENTORY_LIST_NAME; +} + +void fill_items_with_menu_items(std::vector<std::string>& items, LLMenuGL& menu) +{ + LLView::child_list_const_iter_t itor; + for (itor = menu.beginChild(); itor != menu.endChild(); ++itor) + { + std::string name = (*itor)->getName(); + items.push_back(name); + } +} + +// virtual +void LLPlacesLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +{ + 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 + { + fill_items_with_menu_items(items, menu); + + // Disabled items are processed via LLLandmarksPanel::isActionEnabled() + // they should be synchronized with Places/My Landmarks/Gear menu. See EXT-1601 + } + + hideContextEntries(menu, items, disabled_items); +} + + + +void LLPlacesFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +{ + { + std::vector<std::string> items; + std::vector<std::string> disabled_items; + + LLInventoryPanel* inv_panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); + bool is_open = false; + if (inv_panel) + { + LLFolderViewFolder* folder = dynamic_cast<LLFolderViewFolder*>(inv_panel->getRootFolder()->getItemByID(mUUID)); + is_open = (NULL != folder) && folder->isOpen(); + } + + // collect all items' names + fill_items_with_menu_items(items, menu); + + // remove expand or collapse menu item depend on folder state + std::string collapse_expand_item_to_hide(is_open ? "expand" : "collapse"); + std::vector<std::string>::iterator it = std::find(items.begin(), items.end(), collapse_expand_item_to_hide); + if (it != items.end()) items.erase(it); + + // Disabled items are processed via LLLandmarksPanel::isActionEnabled() + // they should be synchronized with Places/My Landmarks/Gear menu. See EXT-1601 + + // repeat parent functionality + sSelf = this; // necessary for "New Folder" functionality + + hideContextEntries(menu, items, disabled_items); + } +} + +//virtual +void LLPlacesFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) +{ + if ("expand" == action) + { + LLFolderViewFolder* act_folder = getFolder(); + act_folder->toggleOpen(); + } + else if ("collapse" == action) + { + LLFolderViewFolder* act_folder = getFolder(); + act_folder->toggleOpen(); + } + else + { + LLFolderBridge::performAction(folder, model, action); + } +} + +LLFolderViewFolder* LLPlacesFolderBridge::getFolder() +{ + LLFolderViewFolder* folder = NULL; + LLInventoryPanel* inv_panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); + if (inv_panel) + { + folder = dynamic_cast<LLFolderViewFolder*>(inv_panel->getRootFolder()->getItemByID(mUUID)); + } + + return folder; +} + +// virtual +LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge( + LLAssetType::EType asset_type, + LLAssetType::EType actual_asset_type, + LLInventoryType::EType inv_type, + LLInventoryPanel* inventory, + const LLUUID& uuid, + U32 flags/* = 0x00*/) const +{ + LLInvFVBridge* new_listener = NULL; + switch(asset_type) + { + 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 LLPlacesLandmarkBridge(inv_type, inventory, uuid, flags); + break; + case LLAssetType::AT_CATEGORY: + if (actual_asset_type == LLAssetType::AT_LINK_FOLDER) + { + // *TODO: Create a link folder handler instead if it is necessary + new_listener = LLInventoryFVBridgeBuilder::createBridge( + asset_type, + actual_asset_type, + inv_type, + inventory, + uuid, + flags); + break; + } + new_listener = new LLPlacesFolderBridge(inv_type, inventory, uuid); + break; + default: + new_listener = LLInventoryFVBridgeBuilder::createBridge( + asset_type, + actual_asset_type, + inv_type, + inventory, + uuid, + flags); + } + return new_listener; +} + +// EOF diff --git a/indra/newview/llplacesinventorybridge.h b/indra/newview/llplacesinventorybridge.h new file mode 100644 index 0000000000..66a8e8e54d --- /dev/null +++ b/indra/newview/llplacesinventorybridge.h @@ -0,0 +1,91 @@ +/** + * @file llplacesinventorybridge.h + * @brief Declaration of the Inventory-Folder-View-Bridge classes for Places 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_LLPLACESINVENTORYBRIDGE_H +#define LL_LLPLACESINVENTORYBRIDGE_H + +#include "llinventorybridge.h" + +class LLFolderViewFolder; + +/** + * Overridden version of the Inventory-Folder-View-Bridge for Places Panel (Landmarks Tab) + */ +class LLPlacesLandmarkBridge : public LLLandmarkBridge +{ + friend class LLPlacesInventoryBridgeBuilder; + +public: + /*virtual*/ void buildContextMenu(LLMenuGL& menu, U32 flags); + +protected: + LLPlacesLandmarkBridge(LLInventoryType::EType type, LLInventoryPanel* inventory, const LLUUID& uuid, U32 flags = 0x00) + : LLLandmarkBridge(inventory, uuid, flags) {mInvType = type;} +}; + +/** + * Overridden version of the Inventory-Folder-View-Bridge for Folders + */ +class LLPlacesFolderBridge : public LLFolderBridge +{ + friend class LLPlacesInventoryBridgeBuilder; + +public: + /*virtual*/ void buildContextMenu(LLMenuGL& menu, U32 flags); + /*virtual*/ void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action); + +protected: + LLPlacesFolderBridge(LLInventoryType::EType type, LLInventoryPanel* inventory, const LLUUID& uuid) + : LLFolderBridge(inventory, uuid) {mInvType = type;} + + LLFolderViewFolder* getFolder(); +}; + + +/** + * This class intended to override default InventoryBridgeBuilder for Inventory Panel. + * + * It builds Bridges for Landmarks and Folders in Places Landmarks Panel + */ +class LLPlacesInventoryBridgeBuilder : public LLInventoryFVBridgeBuilder +{ +public: + /*virtual*/ LLInvFVBridge* createBridge( + LLAssetType::EType asset_type, + LLAssetType::EType actual_asset_type, + LLInventoryType::EType inv_type, + LLInventoryPanel* inventory, + const LLUUID& uuid, + U32 flags = 0x00) const; +}; + +#endif // LL_LLPLACESINVENTORYBRIDGE_H diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp index dbe6079ed5..02e11cefad 100644 --- a/indra/newview/llpolymesh.cpp +++ b/indra/newview/llpolymesh.cpp @@ -40,6 +40,7 @@ #include "llviewercontrol.h" #include "llxmltree.h" #include "llvoavatar.h" +#include "llwearable.h" #include "lldir.h" #include "llvolume.h" #include "llendianswizzle.h" @@ -1117,6 +1118,13 @@ BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info) return TRUE; } +/*virtual*/ LLViewerVisualParam * LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const +{ + LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar); + *new_param = *this; + return new_param; +} + //----------------------------------------------------------------------------- // apply() //----------------------------------------------------------------------------- diff --git a/indra/newview/llpolymesh.h b/indra/newview/llpolymesh.h index c23617749f..709b176c8d 100644 --- a/indra/newview/llpolymesh.h +++ b/indra/newview/llpolymesh.h @@ -46,6 +46,7 @@ class LLSkinJoint; class LLVOAvatar; +class LLWearable; //#define USE_STRIPS // Use tri-strips for rendering. @@ -416,6 +417,8 @@ public: // This sets mInfo and calls initialization functions BOOL setInfo(LLPolySkeletalDistortionInfo *info); + /*virtual*/ LLViewerVisualParam * cloneParam(LLWearable* wearable) const; + // LLVisualParam Virtual functions ///*virtual*/ BOOL parseData(LLXmlTreeNode* node); /*virtual*/ void apply( ESex sex ); diff --git a/indra/newview/llpolymorph.cpp b/indra/newview/llpolymorph.cpp index 3a57b6f9f7..924b1a4d6e 100644 --- a/indra/newview/llpolymorph.cpp +++ b/indra/newview/llpolymorph.cpp @@ -37,6 +37,7 @@ #include "llpolymorph.h" #include "llvoavatar.h" +#include "llwearable.h" #include "llxmltree.h" #include "llendianswizzle.h" @@ -301,6 +302,13 @@ BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info) return TRUE; } +/*virtual*/ LLViewerVisualParam * LLPolyMorphTarget::cloneParam(LLWearable* wearable) const +{ + LLPolyMorphTarget *new_param = new LLPolyMorphTarget(mMesh); + *new_param = *this; + return new_param; +} + #if 0 // obsolete //----------------------------------------------------------------------------- // parseData() diff --git a/indra/newview/llpolymorph.h b/indra/newview/llpolymorph.h index f8dd52ca32..5089fc2e8a 100644 --- a/indra/newview/llpolymorph.h +++ b/indra/newview/llpolymorph.h @@ -42,6 +42,7 @@ class LLPolyMeshSharedData; class LLVOAvatar; class LLVector2; class LLViewerJointCollisionVolume; +class LLWearable; //----------------------------------------------------------------------------- // LLPolyMorphData() @@ -153,6 +154,8 @@ public: // This sets mInfo and calls initialization functions BOOL setInfo(LLPolyMorphTargetInfo *info); + /*virtual*/ LLViewerVisualParam * cloneParam(LLWearable* wearable) const; + // LLVisualParam Virtual functions ///*virtual*/ BOOL parseData(LLXmlTreeNode* node); /*virtual*/ void apply( ESex sex ); diff --git a/indra/newview/llscrollingpanelparam.cpp b/indra/newview/llscrollingpanelparam.cpp new file mode 100644 index 0000000000..0a520ff65f --- /dev/null +++ b/indra/newview/llscrollingpanelparam.cpp @@ -0,0 +1,388 @@ +/** + * @file llscrollingpanelparam.cpp + * @brief UI panel for a list of visual param panels + * + * $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 "llscrollingpanelparam.h" +#include "llviewerjointmesh.h" +#include "llviewervisualparam.h" +#include "llwearable.h" +#include "llviewervisualparam.h" +#include "lltoolmorph.h" +#include "lltrans.h" +#include "llbutton.h" +#include "llsliderctrl.h" +#include "llagent.h" +#include "llvoavatarself.h" + +// Constants for LLPanelVisualParam +const F32 LLScrollingPanelParam::PARAM_STEP_TIME_THRESHOLD = 0.25f; + +const S32 LLScrollingPanelParam::BTN_BORDER = 2; +const S32 LLScrollingPanelParam::PARAM_HINT_WIDTH = 128; +const S32 LLScrollingPanelParam::PARAM_HINT_HEIGHT = 128; +const S32 LLScrollingPanelParam::PARAM_HINT_LABEL_HEIGHT = 16; +const S32 LLScrollingPanelParam::PARAM_PANEL_WIDTH = 2 * (3* BTN_BORDER + PARAM_HINT_WIDTH + LLPANEL_BORDER_WIDTH); +const S32 LLScrollingPanelParam::PARAM_PANEL_HEIGHT = 2 * BTN_BORDER + PARAM_HINT_HEIGHT + PARAM_HINT_LABEL_HEIGHT + 4 * LLPANEL_BORDER_WIDTH; + +// LLScrollingPanelParam +//static +S32 LLScrollingPanelParam::sUpdateDelayFrames = 0; + +LLScrollingPanelParam::LLScrollingPanelParam( const LLPanel::Params& panel_params, + LLViewerJointMesh* mesh, LLViewerVisualParam* param, BOOL allow_modify, LLWearable* wearable ) + : LLScrollingPanel( panel_params ), + mParam(param), + mAllowModify(allow_modify), + mWearable(wearable) +{ + LLUICtrlFactory::getInstance()->buildPanel(this, "panel_scrolling_param.xml"); + + static LLUICachedControl<S32> slider_ctrl_height ("UISliderctrlHeight", 0); + S32 pos_x = 2 * LLPANEL_BORDER_WIDTH; + S32 pos_y = 3 * LLPANEL_BORDER_WIDTH + slider_ctrl_height; + F32 min_weight = param->getMinWeight(); + F32 max_weight = param->getMaxWeight(); + + mHintMin = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, param, min_weight); + pos_x += PARAM_HINT_WIDTH + 3 * BTN_BORDER; + mHintMax = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, param, max_weight ); + + mHintMin->setAllowsUpdates( FALSE ); + mHintMax->setAllowsUpdates( FALSE ); + childSetValue("param slider", weightToPercent(param->getWeight())); + + std::string display_name = LLTrans::getString(param->getDisplayName()); + childSetLabelArg("param slider", "[DESC]", display_name); + childSetEnabled("param slider", mAllowModify); + childSetCommitCallback("param slider", LLScrollingPanelParam::onSliderMoved, this); + + // *TODO: Translate + std::string min_name = param->getMinDisplayName(); + std::string max_name = param->getMaxDisplayName(); + childSetValue("min param text", min_name); + childSetValue("max param text", max_name); + + LLButton* less = getChild<LLButton>("less"); + if (less) + { + less->setMouseDownCallback( LLScrollingPanelParam::onHintMinMouseDown, this ); + less->setMouseUpCallback( LLScrollingPanelParam::onHintMinMouseUp, this ); + less->setHeldDownCallback( LLScrollingPanelParam::onHintMinHeldDown, this ); + less->setHeldDownDelay( PARAM_STEP_TIME_THRESHOLD ); + } + + LLButton* more = getChild<LLButton>("more"); + if (more) + { + more->setMouseDownCallback( LLScrollingPanelParam::onHintMaxMouseDown, this ); + more->setMouseUpCallback( LLScrollingPanelParam::onHintMaxMouseUp, this ); + more->setHeldDownCallback( LLScrollingPanelParam::onHintMaxHeldDown, this ); + more->setHeldDownDelay( PARAM_STEP_TIME_THRESHOLD ); + } + + setVisible(FALSE); + setBorderVisible( FALSE ); +} + +LLScrollingPanelParam::~LLScrollingPanelParam() +{ +} +void LLScrollingPanelParam::updatePanel(BOOL allow_modify) +{ + LLViewerVisualParam* param = mHintMin->getVisualParam(); + + if (!mWearable) + { + // not editing a wearable just now, no update necessary + return; + } + F32 current_weight = mWearable->getVisualParamWeight( param->getID() ); + childSetValue("param slider", weightToPercent( current_weight ) ); + mHintMin->requestUpdate( sUpdateDelayFrames++ ); + mHintMax->requestUpdate( sUpdateDelayFrames++ ); + + mAllowModify = allow_modify; + childSetEnabled("param slider", mAllowModify); + childSetEnabled("less", mAllowModify); + childSetEnabled("more", mAllowModify); +} + +void LLScrollingPanelParam::setVisible( BOOL visible ) +{ + if( getVisible() != visible ) + { + LLPanel::setVisible( visible ); + mHintMin->setAllowsUpdates( visible ); + mHintMax->setAllowsUpdates( visible ); + + if( visible ) + { + mHintMin->setUpdateDelayFrames( sUpdateDelayFrames++ ); + mHintMax->setUpdateDelayFrames( sUpdateDelayFrames++ ); + } + } +} + +void LLScrollingPanelParam::draw() +{ + if( !mWearable ) + { + return; + } + + childSetVisible("less", mHintMin->getVisible()); + childSetVisible("more", mHintMax->getVisible()); + + // Draw all the children except for the labels + childSetVisible( "min param text", FALSE ); + childSetVisible( "max param text", FALSE ); + LLPanel::draw(); + + // Draw the hints over the "less" and "more" buttons. + glPushMatrix(); + { + const LLRect& r = mHintMin->getRect(); + F32 left = (F32)(r.mLeft + BTN_BORDER); + F32 bot = (F32)(r.mBottom + BTN_BORDER); + glTranslatef(left, bot, 0.f); + mHintMin->draw(); + } + glPopMatrix(); + + glPushMatrix(); + { + const LLRect& r = mHintMax->getRect(); + F32 left = (F32)(r.mLeft + BTN_BORDER); + F32 bot = (F32)(r.mBottom + BTN_BORDER); + glTranslatef(left, bot, 0.f); + mHintMax->draw(); + } + glPopMatrix(); + + + // Draw labels on top of the buttons + childSetVisible( "min param text", TRUE ); + drawChild(getChild<LLView>("min param text"), BTN_BORDER, BTN_BORDER); + + childSetVisible( "max param text", TRUE ); + drawChild(getChild<LLView>("max param text"), BTN_BORDER, BTN_BORDER); +} + +// static +void LLScrollingPanelParam::onSliderMoved(LLUICtrl* ctrl, void* userdata) +{ + LLSliderCtrl* slider = (LLSliderCtrl*) ctrl; + LLScrollingPanelParam* self = (LLScrollingPanelParam*) userdata; + LLViewerVisualParam* param = self->mParam; + + F32 current_weight = self->mWearable->getVisualParamWeight( param->getID() ); + F32 new_weight = self->percentToWeight( (F32)slider->getValue().asReal() ); + if (current_weight != new_weight ) + { + self->mWearable->setVisualParamWeight( param->getID(), new_weight, TRUE ); + gAgent.getAvatarObject()->updateVisualParams(); + } +} + +// static +void LLScrollingPanelParam::onSliderMouseDown(LLUICtrl* ctrl, void* userdata) +{ +} + +// static +void LLScrollingPanelParam::onSliderMouseUp(LLUICtrl* ctrl, void* userdata) +{ + LLScrollingPanelParam* self = (LLScrollingPanelParam*) userdata; + + LLVisualParamHint::requestHintUpdates( self->mHintMin, self->mHintMax ); +} + +// static +void LLScrollingPanelParam::onHintMinMouseDown( void* userdata ) +{ + LLScrollingPanelParam* self = (LLScrollingPanelParam*) userdata; + self->onHintMouseDown( self->mHintMin ); +} + +// static +void LLScrollingPanelParam::onHintMaxMouseDown( void* userdata ) +{ + LLScrollingPanelParam* self = (LLScrollingPanelParam*) userdata; + self->onHintMouseDown( self->mHintMax ); +} + + +void LLScrollingPanelParam::onHintMouseDown( LLVisualParamHint* hint ) +{ + // morph towards this result + F32 current_weight = mWearable->getVisualParamWeight( hint->getVisualParam()->getID() ); + + // if we have maxed out on this morph, we shouldn't be able to click it + if( hint->getVisualParamWeight() != current_weight ) + { + mMouseDownTimer.reset(); + mLastHeldTime = 0.f; + } +} + +// static +void LLScrollingPanelParam::onHintMinHeldDown( void* userdata ) +{ + LLScrollingPanelParam* self = (LLScrollingPanelParam*) userdata; + self->onHintHeldDown( self->mHintMin ); +} + +// static +void LLScrollingPanelParam::onHintMaxHeldDown( void* userdata ) +{ + LLScrollingPanelParam* self = (LLScrollingPanelParam*) userdata; + self->onHintHeldDown( self->mHintMax ); +} + +void LLScrollingPanelParam::onHintHeldDown( LLVisualParamHint* hint ) +{ + F32 current_weight = mWearable->getVisualParamWeight( hint->getVisualParam()->getID() ); + + if (current_weight != hint->getVisualParamWeight() ) + { + const F32 FULL_BLEND_TIME = 2.f; + F32 elapsed_time = mMouseDownTimer.getElapsedTimeF32() - mLastHeldTime; + mLastHeldTime += elapsed_time; + + F32 new_weight; + if (current_weight > hint->getVisualParamWeight() ) + { + new_weight = current_weight - (elapsed_time / FULL_BLEND_TIME); + } + else + { + new_weight = current_weight + (elapsed_time / FULL_BLEND_TIME); + } + + // Make sure we're not taking the slider out of bounds + // (this is where some simple UI limits are stored) + F32 new_percent = weightToPercent(new_weight); + LLSliderCtrl* slider = getChild<LLSliderCtrl>("param slider"); + if (slider) + { + if (slider->getMinValue() < new_percent + && new_percent < slider->getMaxValue()) + { + mWearable->setVisualParamWeight( hint->getVisualParam()->getID(), new_weight, TRUE); + gAgent.getAvatarObject()->updateVisualParams(); + + slider->setValue( weightToPercent( new_weight ) ); + } + } + } +} + +// static +void LLScrollingPanelParam::onHintMinMouseUp( void* userdata ) +{ + LLScrollingPanelParam* self = (LLScrollingPanelParam*) userdata; + + F32 elapsed_time = self->mMouseDownTimer.getElapsedTimeF32(); + + LLVisualParamHint* hint = self->mHintMin; + + if (elapsed_time < PARAM_STEP_TIME_THRESHOLD) + { + // step in direction + F32 current_weight = self->mWearable->getVisualParamWeight( hint->getVisualParam()->getID() ); + F32 range = self->mHintMax->getVisualParamWeight() - self->mHintMin->getVisualParamWeight(); + // step a fraction in the negative directiona + F32 new_weight = current_weight - (range / 10.f); + F32 new_percent = self->weightToPercent(new_weight); + LLSliderCtrl* slider = self->getChild<LLSliderCtrl>("param slider"); + if (slider) + { + if (slider->getMinValue() < new_percent + && new_percent < slider->getMaxValue()) + { + self->mWearable->setVisualParamWeight(hint->getVisualParam()->getID(), new_weight, TRUE); + slider->setValue( self->weightToPercent( new_weight ) ); + } + } + } + + LLVisualParamHint::requestHintUpdates( self->mHintMin, self->mHintMax ); +} + +void LLScrollingPanelParam::onHintMaxMouseUp( void* userdata ) +{ + LLScrollingPanelParam* self = (LLScrollingPanelParam*) userdata; + + F32 elapsed_time = self->mMouseDownTimer.getElapsedTimeF32(); + + LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); + if (avatar) + { + LLVisualParamHint* hint = self->mHintMax; + + if (elapsed_time < PARAM_STEP_TIME_THRESHOLD) + { + // step in direction + F32 current_weight = self->mWearable->getVisualParamWeight( hint->getVisualParam()->getID() ); + F32 range = self->mHintMax->getVisualParamWeight() - self->mHintMin->getVisualParamWeight(); + // step a fraction in the negative direction + F32 new_weight = current_weight + (range / 10.f); + F32 new_percent = self->weightToPercent(new_weight); + LLSliderCtrl* slider = self->getChild<LLSliderCtrl>("param slider"); + if (slider) + { + if (slider->getMinValue() < new_percent + && new_percent < slider->getMaxValue()) + { + self->mWearable->setVisualParamWeight(hint->getVisualParam()->getID(), new_weight, TRUE); + slider->setValue( self->weightToPercent( new_weight ) ); + } + } + } + } + + LLVisualParamHint::requestHintUpdates( self->mHintMin, self->mHintMax ); +} + + +F32 LLScrollingPanelParam::weightToPercent( F32 weight ) +{ + LLViewerVisualParam* param = mParam; + return (weight - param->getMinWeight()) / (param->getMaxWeight() - param->getMinWeight()) * 100.f; +} + +F32 LLScrollingPanelParam::percentToWeight( F32 percent ) +{ + LLViewerVisualParam* param = mParam; + return percent / 100.f * (param->getMaxWeight() - param->getMinWeight()) + param->getMinWeight(); +} diff --git a/indra/newview/llscrollingpanelparam.h b/indra/newview/llscrollingpanelparam.h new file mode 100644 index 0000000000..8c5db64816 --- /dev/null +++ b/indra/newview/llscrollingpanelparam.h @@ -0,0 +1,100 @@ +/** + * @file llscrollingpanelparam.h + * @brief the scrolling panel containing a list of visual param + * panels + * + * $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_SCROLLINGPANELPARAM_H +#define LL_SCROLLINGPANELPARAM_H + +#include "llpanel.h" +#include "llscrollingpanellist.h" + +class LLViewerJointMesh; +class LLViewerVisualParam; +class LLWearable; +class LLVisualParamHint; +class LLViewerVisualParam; + +class LLScrollingPanelParam : public LLScrollingPanel +{ +public: + LLScrollingPanelParam( const LLPanel::Params& panel_params, + LLViewerJointMesh* mesh, LLViewerVisualParam* param, BOOL allow_modify, LLWearable* wearable ); + virtual ~LLScrollingPanelParam(); + + virtual void draw(); + virtual void setVisible( BOOL visible ); + virtual void updatePanel(BOOL allow_modify); + + static void onSliderMouseDown(LLUICtrl* ctrl, void* userdata); + static void onSliderMoved(LLUICtrl* ctrl, void* userdata); + static void onSliderMouseUp(LLUICtrl* ctrl, void* userdata); + + static void onHintMinMouseDown(void* userdata); + static void onHintMinHeldDown(void* userdata); + static void onHintMaxMouseDown(void* userdata); + static void onHintMaxHeldDown(void* userdata); + static void onHintMinMouseUp(void* userdata); + static void onHintMaxMouseUp(void* userdata); + + void onHintMouseDown( LLVisualParamHint* hint ); + void onHintHeldDown( LLVisualParamHint* hint ); + + F32 weightToPercent( F32 weight ); + F32 percentToWeight( F32 percent ); + +public: + // Constants for LLPanelVisualParam + const static F32 PARAM_STEP_TIME_THRESHOLD; + + const static S32 BTN_BORDER; + const static S32 PARAM_HINT_WIDTH; + const static S32 PARAM_HINT_HEIGHT; + const static S32 PARAM_HINT_LABEL_HEIGHT; + const static S32 PARAM_PANEL_WIDTH; + const static S32 PARAM_PANEL_HEIGHT; + + +public: + LLViewerVisualParam* mParam; + LLPointer<LLVisualParamHint> mHintMin; + LLPointer<LLVisualParamHint> mHintMax; + static S32 sUpdateDelayFrames; + +protected: + LLTimer mMouseDownTimer; // timer for how long mouse has been held down on a hint. + F32 mLastHeldTime; + + BOOL mAllowModify; + LLWearable *mWearable; +}; + +#endif diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 1ea9655b26..d68897b64f 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -2460,8 +2460,7 @@ BOOL LLSelectMgr::selectGetOwner(LLUUID& result_id, std::string& name) BOOL public_owner = (first_id.isNull() && !first_group_owned); if (first_group_owned) { - // *TODO: We don't have group inspectors yet - name = LLSLURL::buildCommand("group", first_id, "about"); + name = LLSLURL::buildCommand("group", first_id, "inspect"); } else if(!public_owner) { @@ -3590,6 +3589,9 @@ void LLSelectMgr::sendAttach(U8 attachment_point) return; } +#if ENABLE_MULTIATTACHMENTS + attachment_point |= ATTACHMENT_ADD; +#endif BOOL build_mode = LLToolMgr::getInstance()->inEdit(); // Special case: Attach to default location for this object. if (0 == attachment_point || diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 296502ff16..6e757ef976 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -660,7 +660,7 @@ private: static void packDeRezHeader(void* user_data); static void packObjectID( LLSelectNode* node, void *); static void packObjectIDAsParam(LLSelectNode* node, void *); - static void packObjectIDAndRotation( LLSelectNode* node, void *); + static void packObjectIDAndRotation(LLSelectNode* node, void *); static void packObjectLocalID(LLSelectNode* node, void *); static void packObjectClickAction(LLSelectNode* node, void* data); static void packObjectIncludeInSearch(LLSelectNode* node, void* data); diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index 2be0aa40d2..ff95f8adce 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -427,7 +427,16 @@ void LLSideTray::createButtons () void LLSideTray::onTabButtonClick(string name) { - + LLSideTrayTab* side_bar = getTab(name); + + if(side_bar == mActiveTab) + { + if(mCollapsed) + expandSideBar(); + else + collapseSideBar(); + return; + } selectTabByName (name); if(mCollapsed) expandSideBar(); @@ -550,6 +559,15 @@ void LLSideTray::highlightFocused() } +BOOL LLSideTray::handleScrollWheel(S32 x, S32 y, S32 mask) +{ + BOOL ret = LLPanel::handleScrollWheel(x,y,mask); + + if(!ret && childFromPoint(x,y) != 0 ) + return TRUE;//mouse wheel over sidetray buttons, eat mouse wheel + return ret; +} + //virtual BOOL LLSideTray::handleMouseDown (S32 x, S32 y, MASK mask) { @@ -632,7 +650,9 @@ LLPanel* LLSideTray::showPanel (const std::string& panel_name, const LLSD& para LLView* view = (*child_it)->findChildView(panel_name,true); if(view) { - onTabButtonClick((*child_it)->getName()); + selectTabByName ((*child_it)->getName()); + if(mCollapsed) + expandSideBar(); LLSideTrayPanelContainer* container = dynamic_cast<LLSideTrayPanelContainer*>(view->getParent()); if(container) diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h index 13acbbb659..6ea6bafac9 100644 --- a/indra/newview/llsidetray.h +++ b/indra/newview/llsidetray.h @@ -203,6 +203,7 @@ public: bool addChild (LLView* view, S32 tab_group); BOOL handleMouseDown (S32 x, S32 y, MASK mask); + BOOL handleScrollWheel(S32 x, S32 y, S32 mask); void reshape (S32 width, S32 height, BOOL called_from_parent = TRUE); S32 getTrayWidth(); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 7bf0d31d94..9f317803ce 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -659,8 +659,11 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) return; } - group->mLastUpdateDistance = group->mDistance; - group->mLastUpdateViewAngle = group->mViewAngle; + if (group->changeLOD()) + { + group->mLastUpdateDistance = group->mDistance; + group->mLastUpdateViewAngle = group->mViewAngle; + } LLFastTimer ftm(FTM_REBUILD_VBO); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 26c8030dd1..3d0e25a734 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -120,8 +120,6 @@ #include "llnotify.h" #include "llpanelavatar.h" #include "llavatarpropertiesprocessor.h" -#include "llpaneldirbrowser.h" -#include "llpaneldirland.h" #include "llpanelevent.h" #include "llpanelclassified.h" #include "llpanelpick.h" @@ -2527,15 +2525,6 @@ void register_viewer_callbacks(LLMessageSystem* msg) msg->setHandlerFunc("PlacesReply", process_places_reply); msg->setHandlerFunc("GroupNoticesListReply", LLPanelGroupNotices::processGroupNoticesListReply); - msg->setHandlerFunc("DirPlacesReply", LLPanelDirBrowser::processDirPlacesReply); - msg->setHandlerFunc("DirPeopleReply", LLPanelDirBrowser::processDirPeopleReply); - msg->setHandlerFunc("DirEventsReply", LLPanelDirBrowser::processDirEventsReply); - msg->setHandlerFunc("DirGroupsReply", LLPanelDirBrowser::processDirGroupsReply); - //msg->setHandlerFunc("DirPicksReply", LLPanelDirBrowser::processDirPicksReply); - msg->setHandlerFunc("DirClassifiedReply", LLPanelDirBrowser::processDirClassifiedReply); - msg->setHandlerFunc("DirLandReply", LLPanelDirBrowser::processDirLandReply); - //msg->setHandlerFunc("DirPopularReply",LLPanelDirBrowser::processDirPopularReply); - msg->setHandlerFunc("AvatarPickerReply", LLFloaterAvatarPicker::processAvatarPickerReply); msg->setHandlerFunc("MapLayerReply", LLWorldMap::processMapLayerReply); diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index b0930cd86d..4dccdfd7e6 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -41,7 +41,6 @@ #include "llviewercontrol.h" #include "llfloaterbuycurrency.h" #include "llfloaterchat.h" -#include "llfloaterdirectory.h" // to spawn search #include "llfloaterlagmeter.h" #include "llfloaterregioninfo.h" #include "llfloaterscriptdebug.h" diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 67a0528a06..6714fe908f 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -45,29 +45,6 @@ #include "llnotificationmanager.h" -// IM session ID can be the same as Avatar UUID. (See LLIMMgr::computeSessionID) -// Probably notification ID also can be the same as Avatar UUID. -// In case when session ID & notification ID are the same it will be impossible to add both -// appropriate Items into Flat List. -// Functions below are intended to wrap passed LLUUID into LLSD value with different "type". -// Use them anywhere you need to add, get, remove items via the list -inline -LLSD get_notification_value(const LLUUID& notification_id) -{ - return LLSD() - .insert("type", "notification") - .insert("uuid", notification_id); -} - -inline -LLSD get_session_value(const LLUUID& session_id) -{ - return LLSD() - .insert("type", "im_chiclet") - .insert("uuid", session_id); -} - - //--------------------------------------------------------------------------------- LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLDockableFloater(NULL, key), mChannel(NULL), @@ -157,7 +134,7 @@ LLSysWellWindow::~LLSysWellWindow() //--------------------------------------------------------------------------------- void LLSysWellWindow::addItem(LLSysWellItem::Params p) { - LLSD value = get_notification_value(p.notification_id); + LLSD value = p.notification_id; // do not add clones if( mMessageList->getItemByValue(value)) return; @@ -191,7 +168,7 @@ void LLSysWellWindow::clear() //--------------------------------------------------------------------------------- void LLSysWellWindow::removeItemByID(const LLUUID& id) { - if(mMessageList->removeItemByValue(get_notification_value(id))) + if(mMessageList->removeItemByValue(id)) { handleItemRemoved(IT_NOTIFICATION); reshapeWindow(); @@ -357,7 +334,7 @@ void LLSysWellWindow::reshapeWindow() LLChiclet* LLSysWellWindow::findIMChiclet(const LLUUID& sessionId) { LLChiclet* res = NULL; - RowPanel* panel = mMessageList->getTypedItemByValue<RowPanel>(get_session_value(sessionId)); + RowPanel* panel = mMessageList->getTypedItemByValue<RowPanel>(sessionId); if (panel != NULL) { res = panel->mChiclet; @@ -371,7 +348,7 @@ void LLSysWellWindow::addIMRow(const LLUUID& sessionId, S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId) { RowPanel* item = new RowPanel(this, sessionId, chicletCounter, name, otherParticipantId); - if (mMessageList->insertItemAfter(mSeparator, item, get_session_value(sessionId))) + if (mMessageList->insertItemAfter(mSeparator, item, sessionId)) { handleItemAdded(IT_INSTANT_MESSAGE); } @@ -389,7 +366,7 @@ void LLSysWellWindow::addIMRow(const LLUUID& sessionId, S32 chicletCounter, //--------------------------------------------------------------------------------- void LLSysWellWindow::delIMRow(const LLUUID& sessionId) { - if (mMessageList->removeItemByValue(get_session_value(sessionId))) + if (mMessageList->removeItemByValue(sessionId)) { handleItemRemoved(IT_INSTANT_MESSAGE); } @@ -423,7 +400,7 @@ void LLSysWellWindow::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) { //*TODO get rid of get_session_value, session_id's are unique, cause performance degradation with lots chiclets (IB) - if (mMessageList->getItemByValue(get_session_value(session_id)) == NULL) + if (mMessageList->getItemByValue(session_id) == NULL) { S32 chicletCounter = LLIMModel::getInstance()->getNumUnread(session_id); if (chicletCounter > -1) @@ -443,6 +420,17 @@ void LLSysWellWindow::sessionRemoved(const LLUUID& sessionId) LLBottomTray::getInstance()->getSysWell()->updateUreadIMNotifications(); } +void LLSysWellWindow::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) +{ + //for outgoing ad-hoc and group im sessions only + LLChiclet* chiclet = findIMChiclet(old_session_id); + if (chiclet) + { + chiclet->setSessionId(new_session_id); + mMessageList->updateValue(old_session_id, new_session_id); + } +} + void LLSysWellWindow::handleItemAdded(EItemType added_item_type) { bool should_be_shown = ++mTypedItemsCount[added_item_type] == 1 && anotherTypeExists(added_item_type); diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h index 0c3f4d0587..fa6a1abea4 100644 --- a/indra/newview/llsyswellwindow.h +++ b/indra/newview/llsyswellwindow.h @@ -108,6 +108,7 @@ private: // 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); + void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id); // pointer to a corresponding channel's instance LLNotificationsUI::LLScreenChannel* mChannel; diff --git a/indra/newview/lltexglobalcolor.cpp b/indra/newview/lltexglobalcolor.cpp index e81c3731f7..d0bb9e1cf1 100644 --- a/indra/newview/lltexglobalcolor.cpp +++ b/indra/newview/lltexglobalcolor.cpp @@ -33,6 +33,7 @@ #include "llagent.h" #include "lltexlayer.h" #include "llvoavatar.h" +#include "llwearable.h" #include "lltexglobalcolor.h" //----------------------------------------------------------------------------- @@ -64,7 +65,7 @@ BOOL LLTexGlobalColor::setInfo(LLTexGlobalColorInfo *info) iter++) { LLTexParamGlobalColor* param_color = new LLTexParamGlobalColor(this); - if (!param_color->setInfo(*iter)) + if (!param_color->setInfo(*iter, TRUE)) { mInfo = NULL; return FALSE; @@ -95,10 +96,16 @@ const std::string& LLTexGlobalColor::getName() const // LLTexParamGlobalColor //----------------------------------------------------------------------------- LLTexParamGlobalColor::LLTexParamGlobalColor(LLTexGlobalColor* tex_global_color) : - LLTexLayerParamColor((LLTexLayer*)NULL), + LLTexLayerParamColor(tex_global_color->getAvatar()), mTexGlobalColor(tex_global_color) { - mAvatar = tex_global_color->getAvatar(); +} + +/*virtual*/ LLViewerVisualParam * LLTexParamGlobalColor::cloneParam(LLWearable* wearable) const +{ + LLTexParamGlobalColor *new_param = new LLTexParamGlobalColor(mTexGlobalColor); + *new_param = *this; + return new_param; } void LLTexParamGlobalColor::onGlobalColorChanged(bool set_by_user) diff --git a/indra/newview/lltexglobalcolor.h b/indra/newview/lltexglobalcolor.h index 154b814392..f0d22d317c 100644 --- a/indra/newview/lltexglobalcolor.h +++ b/indra/newview/lltexglobalcolor.h @@ -36,6 +36,7 @@ #include "lltexlayerparams.h" class LLVOAvatar; +class LLWearable; class LLTexGlobalColorInfo; class LLTexGlobalColor @@ -67,7 +68,7 @@ public: ~LLTexGlobalColorInfo(); BOOL parseXml(LLXmlTreeNode* node); - + private: param_color_info_list_t mParamColorInfoList; std::string mName; @@ -77,6 +78,7 @@ class LLTexParamGlobalColor : public LLTexLayerParamColor { public: LLTexParamGlobalColor(LLTexGlobalColor *tex_color); + /*virtual*/ LLViewerVisualParam * cloneParam(LLWearable* wearable) const; protected: /*virtual*/ void onGlobalColorChanged(bool set_by_user); private: diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index 5a5f187415..de8458c0fa 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -41,6 +41,9 @@ #include "llassetuploadresponders.h" #include "lltexlayerparams.h" #include "llui.h" +#include "llagentwearables.h" +#include "llwearable.h" +#include "llviewervisualparam.h" //#include "../tools/imdebug/imdebug.h" @@ -66,90 +69,45 @@ LLBakedUploadData::LLBakedUploadData(const LLVOAvatarSelf* avatar, // static S32 LLTexLayerSetBuffer::sGLByteCount = 0; -S32 LLTexLayerSetBuffer::sGLBumpByteCount = 0; LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* const owner, - S32 width, S32 height, - BOOL has_bump) : + S32 width, S32 height) : // ORDER_LAST => must render these after the hints are created. 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), - mHasBump(has_bump), - mBumpTex(NULL) + mTexLayerSet(owner) { LLTexLayerSetBuffer::sGLByteCount += getSize(); - createBumpTexture() ; } LLTexLayerSetBuffer::~LLTexLayerSetBuffer() { LLTexLayerSetBuffer::sGLByteCount -= getSize(); - - if( mBumpTex.notNull()) + destroyGLTexture(); + for( S32 order = 0; order < ORDER_COUNT; order++ ) { - mBumpTex = NULL ; - LLImageGL::sGlobalTextureMemoryInBytes -= mFullWidth * mFullHeight * 4; - LLTexLayerSetBuffer::sGLBumpByteCount -= mFullWidth * mFullHeight * 4; + LLViewerDynamicTexture::sInstances[order].erase(this); // will fail in all but one case. } } //virtual void LLTexLayerSetBuffer::restoreGLTexture() { - createBumpTexture() ; LLViewerDynamicTexture::restoreGLTexture() ; } //virtual void LLTexLayerSetBuffer::destroyGLTexture() { - if( mBumpTex.notNull() ) - { - mBumpTex = NULL ; - LLImageGL::sGlobalTextureMemoryInBytes -= mFullWidth * mFullHeight * 4; - LLTexLayerSetBuffer::sGLBumpByteCount -= mFullWidth * mFullHeight * 4; - } - LLViewerDynamicTexture::destroyGLTexture() ; } -void LLTexLayerSetBuffer::createBumpTexture() -{ - if( mHasBump ) - { - LLGLSUIDefault gls_ui; - mBumpTex = LLViewerTextureManager::getLocalTexture(FALSE) ; - if(!mBumpTex->createGLTexture()) - { - mBumpTex = NULL ; - return ; - } - - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mBumpTex->getTexName()); - stop_glerror(); - - gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - - 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 += mFullWidth * mFullHeight * 4; - LLTexLayerSetBuffer::sGLBumpByteCount += mFullWidth * mFullHeight * 4; - } -} - // static void LLTexLayerSetBuffer::dumpTotalByteCount() { llinfos << "Composite System GL Buffers: " << (LLTexLayerSetBuffer::sGLByteCount/1024) << "KB" << llendl; - llinfos << "Composite System GL Bump Buffers: " << (LLTexLayerSetBuffer::sGLBumpByteCount/1024) << "KB" << llendl; } void LLTexLayerSetBuffer::requestUpdate() @@ -242,8 +200,6 @@ void LLTexLayerSetBuffer::postRender(BOOL success) BOOL LLTexLayerSetBuffer::render() { - U8* baked_bump_data = NULL; - // Default color mask for tex layer render gGL.setColorMask(true, true); @@ -252,33 +208,6 @@ BOOL LLTexLayerSetBuffer::render() 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, mFullWidth, mFullHeight ); - stop_glerror(); - - if (success) - { - LLGLSUIDefault gls_ui; - - // read back into texture (this is done externally for the color data) - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mBumpTex->getTexName()); - stop_glerror(); - - 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[ mFullWidth * mFullHeight * 4 ]; - glReadPixels(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_bump_data ); - stop_glerror(); - } - } - } // Composite the color data LLGLSUIDefault gls_ui; @@ -294,7 +223,7 @@ BOOL LLTexLayerSetBuffer::render() } else { - readBackAndUpload(baked_bump_data); + readBackAndUpload(); } } @@ -306,7 +235,6 @@ BOOL LLTexLayerSetBuffer::render() mGLTexturep->setGLTextureCreated(true); mNeedsUpdate = FALSE; - delete [] baked_bump_data; return success; } @@ -330,7 +258,7 @@ BOOL LLTexLayerSetBuffer::updateImmediate() return result; } -void LLTexLayerSetBuffer::readBackAndUpload(const U8* baked_bump_data) +void LLTexLayerSetBuffer::readBackAndUpload() { // pointers for storing data to upload U8* baked_color_data = new U8[ mFullWidth * mFullHeight * 4 ]; @@ -358,44 +286,25 @@ void LLTexLayerSetBuffer::readBackAndUpload(const U8* baked_bump_data) // writes into baked_color_data const char* comment_text = NULL; - S32 baked_image_components = mBumpTex.notNull() ? 5 : 4; // red green blue [bump] clothing + S32 baked_image_components = 5; // red green blue [bump] clothing 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 + comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // 5 channels: rgb, heightfield/alpha, mask - S32 i = 0; - for( S32 u = 0; u < mFullWidth; u++ ) - { - 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]; - baked_image_data[5*i + 2] = baked_color_data[4*i + 2]; - baked_image_data[5*i + 3] = baked_color_data[4*i + 3]; // alpha should be correct for eyelashes. - baked_image_data[5*i + 4] = baked_mask_data[i]; - i++; - } - } - } - else + S32 i = 0; + for( S32 u = 0; u < mFullWidth; u++ ) + { + for( S32 v = 0; v < mFullHeight; v++ ) { - S32 i = 0; - for( S32 u = 0; u < mFullWidth; u++ ) - { - 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]; - baked_image_data[4*i + 2] = baked_color_data[4*i + 2]; - baked_image_data[4*i + 3] = baked_color_data[4*i + 3]; // Use alpha, not bump - i++; - } - } + 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] = baked_color_data[4*i + 3]; // alpha should be correct for eyelashes. + baked_image_data[5*i + 4] = baked_mask_data[i]; + i++; } + } LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C; compressedImage->setRate(0.f); @@ -548,23 +457,6 @@ void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid, delete baked_upload_data; } -void LLTexLayerSetBuffer::bindBumpTexture( U32 stage ) -{ - if( mBumpTex.notNull() ) - { - gGL.getTexUnit(stage)->bindManual(LLTexUnit::TT_TEXTURE, mBumpTex->getTexName()); - gGL.getTexUnit(0)->activate(); - - mGLTexturep->updateBindStats(mFullWidth * mFullHeight * 4); - } - else - { - gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(0)->activate(); - } -} - - //----------------------------------------------------------------------------- // LLTexLayerSet // An ordered set of texture layers that get composited into a single texture. @@ -659,7 +551,6 @@ LLTexLayerSet::LLTexLayerSet(LLVOAvatarSelf* const avatar) : mComposite( NULL ), mAvatar( avatar ), mUpdatesEnabled( FALSE ), - mHasBump( FALSE ), mInfo( NULL ) { } @@ -686,16 +577,25 @@ BOOL LLTexLayerSet::setInfo(const LLTexLayerSetInfo *info) iter != info->mLayerInfoList.end(); iter++) { - LLTexLayer* layer = new LLTexLayer( this ); - if (!layer->setInfo(*iter)) + LLTexLayerInterface *layer = NULL; + if ( (*iter)->isUserSettable() ) + { + layer = new LLTexLayerTemplate( this ); + } + else + { + layer = new LLTexLayer(this); + } + // this is the first time this layer (of either type) is being created - make sure you add the parameters to the avatar + if (!layer->setInfo(*iter, NULL)) { mInfo = NULL; return FALSE; } if (!layer->isVisibilityMask()) { - mLayerList.push_back( layer ); - } + mLayerList.push_back( layer ); + } else { mMaskLayerList.push_back(layer); @@ -736,12 +636,12 @@ void LLTexLayerSet::deleteCaches() { for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) { - LLTexLayer* layer = *iter; + LLTexLayerInterface* layer = *iter; layer->deleteCaches(); } for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++) { - LLTexLayer* layer = *iter; + LLTexLayerInterface* layer = *iter; layer->deleteCaches(); } } @@ -772,10 +672,22 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) BOOL render_morph = mAvatar->morphMaskNeedsUpdate(mBakedTexIndex); + // clear buffer area to ensure we don't pick up UI elements + { + 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(); + } + // composite color layers for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) { - LLTexLayer* layer = *iter; + LLTexLayerInterface* layer = *iter; if (layer->getRenderPass() == LLTexLayer::RP_COLOR) { gGL.flush(); @@ -788,44 +700,13 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) } } - renderAlphaMaskTextures(width, height, false); + renderAlphaMaskTextures(x, y, width, height, false); stop_glerror(); return success; } -BOOL LLTexLayerSet::renderBump( S32 x, S32 y, S32 width, S32 height ) -{ - BOOL success = TRUE; - - LLGLSUIDefault gls_ui; - LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE); - - //static S32 bump_layer_count = 1; - - for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) - { - LLTexLayer* layer = *iter; - if (layer->getRenderPass() == LLTexLayer::RP_BUMP) - { -// success &= layer->render(x, y, width, height); - } - } - - // 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.setColorMask(false, true); - - gl_rect_2d_simple( width, height ); - - gGL.setColorMask(true, true); - stop_glerror(); - - return success; -} BOOL LLTexLayerSet::isBodyRegion(const std::string& region) const { @@ -869,11 +750,9 @@ void LLTexLayerSet::createComposite() // Composite other avatars at reduced resolution if( !mAvatar->isSelf() ) { - // TODO: replace with sanity check to ensure not called for non-self avatars -// width /= 2; -// height /= 2; + llerrs << "composites should not be created for non-self avatars!" << llendl; } - mComposite = new LLTexLayerSetBuffer( this, width, height, mHasBump ); + mComposite = new LLTexLayerSetBuffer( this, width, height ); } } @@ -905,44 +784,21 @@ LLTexLayerSetBuffer* LLTexLayerSet::getComposite() 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; - U8* alphaData = layer->getAlphaData(); - if (!alphaData && layer->hasAlphaParams()) - { - LLColor4 net_color; - layer->findNetColor( &net_color ); - // TODO: eliminate need for layer morph mask valid flag - layer->invalidateMorphMasks(); - mAvatar->invalidateMorphMasks(mBakedTexIndex); - layer->renderMorphMasks(mComposite->getOriginX(), mComposite->getOriginY(), width, height, net_color, render_morph); - alphaData = layer->getAlphaData(); - } - if (alphaData) - { - for( S32 i = 0; i < size; i++ ) - { - U8 curAlpha = data[i]; - U16 resultAlpha = curAlpha; - resultAlpha *= (alphaData[i] + 1); - resultAlpha = resultAlpha >> 8; - data[i] = (U8)resultAlpha; - } - } + LLTexLayerInterface* layer = *iter; + layer->gatherAlphaMasks(data, mComposite->getOriginX(),mComposite->getOriginY(), width, height, render_morph); } // Set alpha back to that of our alpha masks. - renderAlphaMaskTextures(width, height, true); + renderAlphaMaskTextures(mComposite->getOriginX(), mComposite->getOriginY(), width, height, true); } -void LLTexLayerSet::renderAlphaMaskTextures(S32 width, S32 height, bool forceClear) +void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear) { const LLTexLayerSetInfo *info = getInfo(); @@ -986,9 +842,9 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 width, S32 height, bool forceCle gGL.getTexUnit(0)->setTextureBlendType( LLTexUnit::TB_REPLACE ); for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++) { - LLTexLayer* layer = *iter; + LLTexLayerInterface* layer = *iter; gGL.flush(); - layer->blendAlphaTexture(width, height); + layer->blendAlphaTexture(x,y,width, height); gGL.flush(); } @@ -1006,23 +862,6 @@ void LLTexLayerSet::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_ 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; - - if (layer->getName().compare(name) == 0) - { - return layer; - } - } - return NULL; -} - //----------------------------------------------------------------------------- // LLTexLayerInfo @@ -1190,7 +1029,7 @@ BOOL LLTexLayerInfo::createVisualParams(LLVOAvatar *avatar) { LLTexLayerParamColorInfo * color_info = *color_info_iter; LLTexLayerParamColor* param_color = new LLTexLayerParamColor(avatar); - if (!param_color->setInfo(color_info)) + if (!param_color->setInfo(color_info, TRUE)) { llwarns << "NULL TexLayer Color Param could not be added to visual param list. Deleting." << llendl; delete param_color; @@ -1204,7 +1043,7 @@ BOOL LLTexLayerInfo::createVisualParams(LLVOAvatar *avatar) { LLTexLayerParamAlphaInfo * alpha_info = *alpha_info_iter; LLTexLayerParamAlpha* param_alpha = new LLTexLayerParamAlpha(avatar); - if (!param_alpha->setInfo(alpha_info)) + if (!param_alpha->setInfo(alpha_info, TRUE)) { llwarns << "NULL TexLayer Alpha Param could not be added to visual param list. Deleting." << llendl; delete param_alpha; @@ -1215,6 +1054,138 @@ BOOL LLTexLayerInfo::createVisualParams(LLVOAvatar *avatar) return success; } +LLTexLayerInterface::LLTexLayerInterface(LLTexLayerSet* const layer_set): + mTexLayerSet( layer_set ), + mMorphMasksValid( FALSE ), + mStaticImageInvalid( FALSE ), + mInfo(NULL), + mHasMorph(FALSE) +{ +} + +LLTexLayerInterface::LLTexLayerInterface(const LLTexLayerInterface &layer, LLWearable *wearable): + mTexLayerSet( layer.mTexLayerSet ) +{ + // don't add visual params for cloned layers + setInfo(layer.getInfo(), wearable); + + mHasMorph = layer.mHasMorph; +} + +BOOL LLTexLayerInterface::setInfo(const LLTexLayerInfo *info, LLWearable* wearable ) // This sets mInfo and calls initialization functions +{ + llassert(mInfo == NULL); + mInfo = info; + //mID = info->mID; // No ID + + mParamColorList.reserve(mInfo->mParamColorInfoList.size()); + for (param_color_info_list_t::const_iterator iter = mInfo->mParamColorInfoList.begin(); + iter != mInfo->mParamColorInfoList.end(); + iter++) + { + LLTexLayerParamColor* param_color; + if (!wearable) + { + param_color = new LLTexLayerParamColor(this); + if (!param_color->setInfo(*iter, TRUE)) + { + mInfo = NULL; + return FALSE; + } + } + else + { + param_color = (LLTexLayerParamColor*)wearable->getVisualParam((*iter)->getID()); + if (!param_color) + { + mInfo = NULL; + return FALSE; + } + } + mParamColorList.push_back( param_color ); + } + + 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; + if (!wearable) + { + param_alpha = new LLTexLayerParamAlpha( this ); + if (!param_alpha->setInfo(*iter, TRUE)) + { + mInfo = NULL; + return FALSE; + } + } + else + { + param_alpha = (LLTexLayerParamAlpha*) wearable->getVisualParam((*iter)->getID()); + if (!param_alpha) + { + mInfo = NULL; + return FALSE; + } + } + mParamAlphaList.push_back( param_alpha ); + } + + return TRUE; +} + +/*virtual*/ void LLTexLayerInterface::requestUpdate() +{ + mTexLayerSet->requestUpdate(); +} + +const std::string& LLTexLayerInterface::getName() const +{ + return mInfo->mName; +} + +LLTexLayerInterface::ERenderPass LLTexLayerInterface::getRenderPass() const +{ + return mInfo->mRenderPass; +} + +const std::string& LLTexLayerInterface::getGlobalColor() const +{ + return mInfo->mGlobalColor; +} + +BOOL LLTexLayerInterface::isVisibilityMask() const +{ + return mInfo->mIsVisibilityMask; +} + +void LLTexLayerInterface::invalidateMorphMasks() +{ + mMorphMasksValid = FALSE; +} + +LLViewerVisualParam* LLTexLayerInterface::getVisualParamPtr(S32 index) +{ + LLViewerVisualParam *result = NULL; + for (param_color_list_t::iterator color_iter = mParamColorList.begin(); color_iter != mParamColorList.end() && !result; ++color_iter) + { + if ((*color_iter)->getID() == index) + { + result = *color_iter; + } + } + for (param_alpha_list_t::iterator alpha_iter = mParamAlphaList.begin(); alpha_iter != mParamAlphaList.end() && !result; ++alpha_iter) + { + if ((*alpha_iter)->getID() == index) + { + result = *alpha_iter; + } + } + + return result; +} + //----------------------------------------------------------------------------- // LLTexLayer // A single texture layer, consisting of: @@ -1228,23 +1199,22 @@ BOOL LLTexLayerInfo::createVisualParams(LLVOAvatar *avatar) // * a texture entry index (TE) // * (optional) one or more alpha parameters (weighted alpha textures) //----------------------------------------------------------------------------- -LLTexLayer::LLTexLayer(LLTexLayerSet* layer_set) : - mTexLayerSet( layer_set ), - mMorphMasksValid( FALSE ), - mStaticImageInvalid( FALSE ), - mInfo(NULL), - mHasMorph(FALSE) +LLTexLayer::LLTexLayer(LLTexLayerSet* const layer_set) : + LLTexLayerInterface( layer_set ), + mLocalTextureObject(NULL) { } -LLTexLayer::LLTexLayer(const LLTexLayer &layer) : - mTexLayerSet( layer.mTexLayerSet ) +LLTexLayer::LLTexLayer(const LLTexLayer &layer, LLWearable *wearable) : + LLTexLayerInterface( layer, wearable ), + mLocalTextureObject(NULL) { - setInfo(layer.getInfo()); - - - mHasMorph = layer.mHasMorph; +} +LLTexLayer::LLTexLayer(const LLTexLayerTemplate &layer_template, LLLocalTextureObject *lto, LLWearable *wearable) : + LLTexLayerInterface( layer_template, wearable ), + mLocalTextureObject(lto) +{ } LLTexLayer::~LLTexLayer() @@ -1267,44 +1237,9 @@ LLTexLayer::~LLTexLayer() // setInfo //----------------------------------------------------------------------------- -BOOL LLTexLayer::setInfo(const LLTexLayerInfo* info) +BOOL LLTexLayer::setInfo(const LLTexLayerInfo* info, LLWearable* wearable ) { - llassert(mInfo == NULL); - mInfo = info; - //mID = info->mID; // No ID - - 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++) - { - LLTexLayerParamColor* param_color = new LLTexLayerParamColor(this); - if (!param_color->setInfo(*iter)) - { - mInfo = NULL; - return FALSE; - } - mParamColorList.push_back( param_color ); - } - - 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)) - { - mInfo = NULL; - return FALSE; - } - mParamAlphaList.push_back( param_alpha ); - } - - return TRUE; + return LLTexLayerInterface::setInfo(info, wearable); } //static @@ -1312,12 +1247,12 @@ void LLTexLayer::calculateTexLayerColor(const param_color_list_t ¶m_list, LL { 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()) - { + { case LLTexLayerParamColor::OP_ADD: net_color += param_net; break; @@ -1330,13 +1265,14 @@ void LLTexLayer::calculateTexLayerColor(const param_color_list_t ¶m_list, LL default: llassert(0); break; - } + } } net_color.clamp(); } -void LLTexLayer::deleteCaches() +/*virtual*/ void LLTexLayer::deleteCaches() { + // Only need to delete caches for alpha params. Color params don't hold extra memory for (param_alpha_list_t::iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++ ) { @@ -1373,7 +1309,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph) { // 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 (!mHasMorph) +/* if (!mHasMorph) { BOOL skip_layer = TRUE; @@ -1394,7 +1330,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph) { return success; } - } + }//*/ renderMorphMasks(x, y, width, height, net_color, render_morph); alpha_mask_specified = TRUE; @@ -1414,7 +1350,19 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph) { { LLViewerTexture* tex = NULL; - if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &tex ) ) + if (mLocalTextureObject && mLocalTextureObject->getImage()) + { + tex = mLocalTextureObject->getImage(); + if (mLocalTextureObject->getID() == IMG_DEFAULT_AVATAR) + { + tex = NULL; + } + } + else + { + llinfos << "lto not defined or image not defined: " << getInfo()->getLocalTexture() << " lto: " << mLocalTextureObject << llendl; + } +// if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) ) { if( tex ) { @@ -1431,10 +1379,10 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph) gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } } - else - { - success = FALSE; - } +// else +// { +// success = FALSE; +// } } } @@ -1484,12 +1432,13 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph) U8* LLTexLayer::getAlphaData() { LLCRC alpha_mask_crc; - const LLUUID& uuid = mTexLayerSet->getAvatar()->getLocalTextureID((ETextureIndex)getInfo()->mLocalTexture); + const LLUUID& uuid = getUUID(); alpha_mask_crc.update((U8*)(&uuid.mData), UUID_BYTES); for (param_alpha_list_t::const_iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++) { const LLTexLayerParamAlpha* param = *iter; + // MULTI-WEARABLE: verify visual parameters used here F32 param_weight = param->getWeight(); alpha_mask_crc.update((U8*)¶m_weight, sizeof(F32)); } @@ -1544,7 +1493,7 @@ BOOL LLTexLayer::findNetColor(LLColor4* net_color) const return FALSE; // No need to draw a separate colored polygon } -BOOL LLTexLayer::blendAlphaTexture(S32 width, S32 height) +BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) { BOOL success = TRUE; @@ -1569,17 +1518,14 @@ BOOL LLTexLayer::blendAlphaTexture(S32 width, S32 height) { if (getInfo()->mLocalTexture >=0 && getInfo()->mLocalTexture < TEX_NUM_INDICES) { - LLViewerTexture* tex = NULL; - if (mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &tex)) + LLViewerTexture* tex = mLocalTextureObject->getImage(); + if (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; - } + 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; } } } @@ -1587,6 +1533,10 @@ BOOL LLTexLayer::blendAlphaTexture(S32 width, S32 height) return success; } +/*virtual*/ void LLTexLayer::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, BOOL render_morph) +{ + addAlphaMask(data, originX, originY, width, height, render_morph); +} BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, BOOL render_morph) { @@ -1627,23 +1577,20 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC // Accumulate the alpha component of the texture if( getInfo()->mLocalTexture != -1 ) { - LLViewerTexture* tex = NULL; - if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &tex ) ) + LLViewerTexture* tex = mLocalTextureObject->getImage(); + if( tex && (tex->getComponents() == 4) ) { - if( tex && (tex->getComponents() == 4) ) - { - LLGLSNoAlphaTest gls_no_alpha_test; + LLGLSNoAlphaTest gls_no_alpha_test; - LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode(); - - gGL.getTexUnit(0)->bind(tex); - gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode(); + + gGL.getTexUnit(0)->bind(tex); + gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - gl_rect_2d_simple_tex( width, height ); + gl_rect_2d_simple_tex( width, height ); - gGL.getTexUnit(0)->setTextureAddressMode(old_mode); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - } + gGL.getTexUnit(0)->setTextureAddressMode(old_mode); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } else { @@ -1686,10 +1633,10 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC gGL.setColorMask(true, true); - if (render_morph && mHasMorph) + if (render_morph && mHasMorph && success) { LLCRC alpha_mask_crc; - const LLUUID& uuid = mTexLayerSet->getAvatar()->getLocalTextureID((ETextureIndex)getInfo()->mLocalTexture); + const LLUUID& uuid = getUUID(); alpha_mask_crc.update((U8*)(&uuid.mData), UUID_BYTES); for (param_alpha_list_t::const_iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++) @@ -1726,106 +1673,269 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC return success; } -// 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 ) +void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height, BOOL render_morph) { - if (!in_data) + S32 size = width * height; + U8* alphaData = getAlphaData(); + if (!alphaData && hasAlphaParams()) { - return FALSE; + LLColor4 net_color; + findNetColor( &net_color ); + // TODO: eliminate need for layer morph mask valid flag + invalidateMorphMasks(); + renderMorphMasks(originX, originY, width, height, net_color, render_morph); + alphaData = getAlphaData(); } - GLenum format_options[4] = { GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA }; - GLenum format = format_options[in_components-1]; - if( is_mask ) + if (alphaData) { - llassert( 1 == in_components ); - format = GL_ALPHA; + for( S32 i = 0; i < size; i++ ) + { + U8 curAlpha = data[i]; + U16 resultAlpha = curAlpha; + resultAlpha *= (alphaData[i] + 1); + resultAlpha = resultAlpha >> 8; + data[i] = (U8)resultAlpha; + } } +} - if( (in_width != SCRATCH_TEX_WIDTH) || (in_height != SCRATCH_TEX_HEIGHT) ) +// private helper function +LLUUID LLTexLayer::getUUID() +{ + LLUUID uuid; + if( getInfo()->mLocalTexture != -1 ) { - LLGLSNoAlphaTest gls_no_alpha_test; + LLViewerTexture* tex = mLocalTextureObject->getImage(); + if (tex) + { + uuid = mLocalTextureObject->getID(); + } + } + if( !getInfo()->mStaticImageFileName.empty() ) + { + LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); + if( tex ) + { + uuid = tex->getID(); + } + } + return uuid; +} - GLenum internal_format_options[4] = { GL_LUMINANCE8, GL_LUMINANCE8_ALPHA8, GL_RGB8, GL_RGBA8 }; - GLenum internal_format = internal_format_options[in_components-1]; - if( is_mask ) - { - llassert( 1 == in_components ); - internal_format = GL_ALPHA8; - } - - U32 name = 0; - LLImageGL::generateTextures(1, &name ); - stop_glerror(); - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, name); - stop_glerror(); +//----------------------------------------------------------------------------- +// LLTexLayerTemplate +// A single texture layer, consisting of: +// * color, consisting of either +// * one or more color parameters (weighted colors) +// * a reference to a global color +// * a fixed color with non-zero alpha +// * opaque white (the default) +// * (optional) a texture defined by either +// * a GUID +// * a texture entry index (TE) +// * (optional) one or more alpha parameters (weighted alpha textures) +//----------------------------------------------------------------------------- +LLTexLayerTemplate::LLTexLayerTemplate(LLTexLayerSet* layer_set) : + LLTexLayerInterface(layer_set) +{ +} - LLImageGL::setManualImage( - GL_TEXTURE_2D, 0, internal_format, - in_width, in_height, - format, GL_UNSIGNED_BYTE, in_data ); - stop_glerror(); +LLTexLayerTemplate::LLTexLayerTemplate(const LLTexLayerTemplate &layer) : + LLTexLayerInterface(layer) +{ +} - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - - gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); +LLTexLayerTemplate::~LLTexLayerTemplate() +{ +} - gl_rect_2d_simple_tex( width, height ); +//----------------------------------------------------------------------------- +// setInfo +//----------------------------------------------------------------------------- - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +/*virtual*/ BOOL LLTexLayerTemplate::setInfo(const LLTexLayerInfo* info, LLWearable* wearable ) +{ + return LLTexLayerInterface::setInfo(info, wearable); +} - LLImageGL::deleteTextures(1, &name ); - stop_glerror(); +U32 LLTexLayerTemplate::updateWearableCache() +{ + mWearableCache.clear(); + + S32 te = mInfo->mLocalTexture; + if (te == -1) + { + //this isn't a cloneable layer + return 0; } - else + EWearableType wearable_type = LLVOAvatarDictionary::getTEWearableType((ETextureIndex)te); + U32 num_wearables = gAgentWearables.getWearableCount(wearable_type); + U32 added = 0; + for (U32 i = 0; i < num_wearables; i++) { - LLGLSNoAlphaTest gls_no_alpha_test; - - if( !mTexLayerSet->getAvatar()->bindScratchTexture(format) ) + LLWearable* wearable = gAgentWearables.getWearable(wearable_type, i); + if (!wearable) { - return FALSE; + continue; } + mWearableCache.push_back(wearable); + added++; + } + return added; +} +LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) +{ + if (mWearableCache.size() <= i || i < 0) + { + return NULL; + } + LLWearable *wearable = mWearableCache[i]; + LLLocalTextureObject *lto = NULL; + LLTexLayer *layer = NULL; + if (wearable) + { + lto = wearable->getLocalTextureObject(mInfo->mLocalTexture); + } + if (lto) + { + layer = lto->getTexLayer(getName()); + } + return layer; +} - glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, in_width, in_height, format, GL_UNSIGNED_BYTE, in_data ); - stop_glerror(); +/*virtual*/ BOOL LLTexLayerTemplate::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph) +{ + BOOL success = TRUE; + updateWearableCache(); + for (wearable_cache_t::const_iterator iter = mWearableCache.begin(); iter!= mWearableCache.end(); iter++) + { + LLWearable* wearable = NULL; + LLLocalTextureObject *lto = NULL; + LLTexLayer *layer = NULL; + wearable = *iter; + if (wearable) + { + lto = wearable->getLocalTextureObject(mInfo->mLocalTexture); + } + if (lto) + { + layer = lto->getTexLayer(getName()); + } + if (layer) + { + wearable->writeToAvatar(FALSE, FALSE); + layer->setLTO(lto); + success &= layer->render(x,y,width,height,render_morph); + } + } - gl_rect_2d_simple_tex( width, height ); + return success; +} - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +/*virtual*/ BOOL LLTexLayerTemplate::blendAlphaTexture( S32 x, S32 y, S32 width, S32 height) // Multiplies a single alpha texture against the frame buffer +{ + BOOL success = TRUE; + U32 num_wearables = updateWearableCache(); + for (U32 i = 0; i < num_wearables; i++) + { + LLTexLayer *layer = getLayer(i); + if (layer) + { + success &= layer->blendAlphaTexture(x,y,width,height); + } } - - return TRUE; + return success; } -void LLTexLayer::requestUpdate() +/*virtual*/ void LLTexLayerTemplate::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, BOOL render_morph) { - mTexLayerSet->requestUpdate(); + U32 num_wearables = updateWearableCache(); + for (U32 i = 0; i < num_wearables; i++) + { + LLTexLayer *layer = getLayer(i); + if (layer) + { + layer->addAlphaMask(data, originX, originY, width, height, render_morph); + } + } } -const std::string& LLTexLayer::getName() const +/*virtual*/ void LLTexLayerTemplate::setHasMorph(BOOL newval) { - return mInfo->mName; + mHasMorph = newval; + U32 num_wearables = updateWearableCache(); + for (U32 i = 0; i < num_wearables; i++) + { + LLTexLayer *layer = getLayer(i); + if (layer) + { + layer->setHasMorph(newval); + } + } } -LLTexLayer::ERenderPass LLTexLayer::getRenderPass() const +/*virtual*/ void LLTexLayerTemplate::deleteCaches() { - return mInfo->mRenderPass; + U32 num_wearables = updateWearableCache(); + for (U32 i = 0; i < num_wearables; i++) + { + LLTexLayer *layer = getLayer(i); + if (layer) + { + layer->deleteCaches(); + } + } } -const std::string& LLTexLayer::getGlobalColor() const + + + +//----------------------------------------------------------------------------- +// finds a specific layer based on a passed in name +//----------------------------------------------------------------------------- +LLTexLayerInterface* LLTexLayerSet::findLayerByName(std::string name) { - return mInfo->mGlobalColor; + for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) + { + LLTexLayerInterface* layer = *iter; + + if (layer->getName().compare(name) == 0) + { + return layer; + } + } + for( layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++ ) + { + LLTexLayerInterface* layer = *iter; + + if (layer->getName().compare(name) == 0) + { + return layer; + } + } + return NULL; } -void LLTexLayer::invalidateMorphMasks() +void LLTexLayerSet::cloneTemplates(LLLocalTextureObject *lto, LLVOAvatarDefines::ETextureIndex tex_index, LLWearable *wearable) { - mMorphMasksValid = FALSE; + // initialize all texlayers with this texture type for this LTO + for( LLTexLayerSet::layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) + { + LLTexLayerTemplate* layer = (LLTexLayerTemplate*)*iter; + if (layer->getInfo()->getLocalTexture() == (S32) tex_index) + { + lto->addTexLayer(layer, wearable); + } } - -BOOL LLTexLayer::isVisibilityMask() const + for( LLTexLayerSet::layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++ ) { - return mInfo->mIsVisibilityMask; + LLTexLayerTemplate* layer = (LLTexLayerTemplate*)*iter; + if (layer->getInfo()->getLocalTexture() == (S32) tex_index) + { + lto->addTexLayer(layer, wearable); + } + } } - //----------------------------------------------------------------------------- // LLTexLayerStaticImageList //----------------------------------------------------------------------------- diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h index 6922eae0e1..2269c3c9a5 100644 --- a/indra/newview/lltexlayer.h +++ b/indra/newview/lltexlayer.h @@ -52,19 +52,15 @@ class LLTexLayerParamColor; class LLTexLayerParamColorInfo; class LLTexLayerParamAlpha; class LLTexLayerParamAlphaInfo; - +class LLWearable; +class LLViewerVisualParam; 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; -//----------------------------------------------------------------------------- -// LLTexLayer -// A single texture layer -// Only exists for llvoavatarself - -class LLTexLayer +class LLTexLayerInterface { public: enum ERenderPass @@ -74,36 +70,36 @@ public: RP_SHINE }; - LLTexLayer(LLTexLayerSet* const layer_set); - LLTexLayer(const LLTexLayer &layer); - ~LLTexLayer(); + LLTexLayerInterface(LLTexLayerSet* const layer_set); + LLTexLayerInterface(const LLTexLayerInterface &layer, LLWearable *wearable); + virtual ~LLTexLayerInterface() {} 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); + virtual BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable ); // This sets mInfo and calls initialization functions + virtual BOOL render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph) = 0; void requestUpdate(); LLTexLayerSet* const getTexLayerSet() const { return mTexLayerSet; } - void deleteCaches(); - U8* getAlphaData(); + virtual void deleteCaches() = 0; void invalidateMorphMasks(); - void setHasMorph(BOOL newval) { mHasMorph = newval; } + virtual void setHasMorph(BOOL newval) { mHasMorph = newval; } BOOL isMorphValid() { return mMorphMasksValid; } const std::string& getName() const; ERenderPass getRenderPass() const; - const std::string& getGlobalColor() const; + const std::string& getGlobalColor() const; - 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); + virtual BOOL blendAlphaTexture( S32 x, S32 y, S32 width, S32 height) = 0; + virtual void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, BOOL render_morph) = 0; BOOL hasAlphaParams() const { return !mParamAlphaList.empty(); } BOOL isVisibilityMask() const; - static void calculateTexLayerColor(const param_color_list_t ¶m_list, LLColor4 &net_color); + LLTexLayerSet* getLayerSet() {return mTexLayerSet;} -private: + LLViewerVisualParam* getVisualParamPtr(S32 index); + + +protected: LLTexLayerSet* const mTexLayerSet; // Layers can have either mParamColorList, mGlobalColor, or mFixedColor. They are looked for in that order. @@ -111,27 +107,96 @@ private: // mGlobalColor name stored in mInfo // mFixedColor value stored in mInfo param_alpha_list_t mParamAlphaList; - + BOOL mMorphMasksValid; - typedef std::map<U32, U8*> alpha_cache_t; - alpha_cache_t mAlphaCache; BOOL mStaticImageInvalid; BOOL mHasMorph; const LLTexLayerInfo *mInfo; + +}; + +//----------------------------------------------------------------------------- +// LLTexLayerTemplate +// Template class +// Only exists for llvoavatarself + +class LLTexLayerTemplate : public LLTexLayerInterface +{ +public: + LLTexLayerTemplate(LLTexLayerSet* const layer_set); + LLTexLayerTemplate(const LLTexLayerTemplate &layer); + /*virtual*/ ~LLTexLayerTemplate(); + + /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph); + /*virtual*/ BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable ); // This sets mInfo and calls initialization functions + /*virtual*/ BOOL blendAlphaTexture( S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer + /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, BOOL render_morph); + /*virtual*/ void setHasMorph(BOOL newval); + /*virtual*/ void deleteCaches(); +private: + U32 updateWearableCache(); + LLTexLayer* getLayer(U32 i); + typedef std::vector<LLWearable*> wearable_cache_t; + wearable_cache_t mWearableCache; + +}; + +//----------------------------------------------------------------------------- +// LLTexLayer +// A single texture layer +// Only exists for llvoavatarself + +class LLTexLayer : public LLTexLayerInterface +{ +public: + LLTexLayer(LLTexLayerSet* const layer_set); + LLTexLayer(const LLTexLayer &layer, LLWearable *wearable); + LLTexLayer(const LLTexLayerTemplate &layer_template, LLLocalTextureObject *lto, LLWearable *wearable); + /*virtual*/ ~LLTexLayer(); + + /*virtual*/ BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable ); // This sets mInfo and calls initialization functions + /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph); + + /*virtual*/ void deleteCaches(); + U8* getAlphaData(); + + BOOL findNetColor(LLColor4* color) const; + /*virtual*/ BOOL blendAlphaTexture( S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer + /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, BOOL render_morph); + BOOL renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, BOOL render_morph); + void addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height, BOOL render_morph); + + void setLTO(LLLocalTextureObject *lto) { mLocalTextureObject = lto; } + LLLocalTextureObject* getLTO() { return mLocalTextureObject; } + + static void calculateTexLayerColor(const param_color_list_t ¶m_list, LLColor4 &net_color); + +private: + LLUUID getUUID(); + + typedef std::map<U32, U8*> alpha_cache_t; + alpha_cache_t mAlphaCache; + LLLocalTextureObject *mLocalTextureObject; }; // Make private class LLTexLayerInfo { friend class LLTexLayer; + friend class LLTexLayerTemplate; + friend class LLTexLayerInterface; public: LLTexLayerInfo(); ~LLTexLayerInfo(); BOOL parseXml(LLXmlTreeNode* node); BOOL createVisualParams(LLVOAvatar *avatar); + BOOL isUserSettable() { return mLocalTexture != -1; } + S32 getLocalTexture() const { return mLocalTexture; } + BOOL getOnlyAlpha() const { return mUseLocalTextureAlphaOnly; } + std::string getName() const { return mName; } private: std::string mName; @@ -174,7 +239,7 @@ public: 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); + void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false); BOOL isBodyRegion(const std::string& region) const; LLTexLayerSetBuffer* getComposite(); @@ -191,28 +256,26 @@ public: void deleteCaches(); void gatherMorphMaskAlpha(U8 *data, S32 width, S32 height); void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components); - void renderAlphaMaskTextures(S32 width, S32 height, bool forceClear = false); - LLTexLayer* findLayerByName(std::string name); + LLTexLayerInterface* findLayerByName(std::string name); + void cloneTemplates(LLLocalTextureObject *lto, LLVOAvatarDefines::ETextureIndex tex_index, LLWearable* wearable); 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; + typedef std::vector<LLTexLayerInterface *> layer_list_t; + private: - typedef std::vector<LLTexLayer *> layer_list_t; layer_list_t mLayerList; layer_list_t mMaskLayerList; LLPointer<LLTexLayerSetBuffer> mComposite; LLVOAvatarSelf* const mAvatar; // Backlink only; don't make this an LLPointer. BOOL mUpdatesEnabled; - BOOL mHasBump; LLVOAvatarDefines::EBakedTextureIndex mBakedTexIndex; @@ -245,14 +308,13 @@ private: class LLTexLayerSetBuffer : public LLViewerDynamicTexture { public: - LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height, BOOL has_bump); + LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height); 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(); @@ -260,8 +322,7 @@ public: void cancelUpload(); BOOL uploadPending() { return mUploadPending; } BOOL render( S32 x, S32 y, S32 width, S32 height ); - void readBackAndUpload(const U8* baked_bump_data); - void createBumpTexture(); + void readBackAndUpload(); static void onTextureUploadComplete(const LLUUID& uuid, void* userdata, @@ -276,17 +337,14 @@ private: void popProjection() const; private: - const BOOL mHasBump; LLTexLayerSet* const mTexLayerSet; 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 static S32 sGLByteCount; - static S32 sGLBumpByteCount; }; // diff --git a/indra/newview/lltexlayerparams.cpp b/indra/newview/lltexlayerparams.cpp index 7a1ee95a65..9cd73c4656 100644 --- a/indra/newview/lltexlayerparams.cpp +++ b/indra/newview/lltexlayerparams.cpp @@ -33,13 +33,14 @@ #include "llagent.h" #include "lltexlayer.h" #include "llvoavatarself.h" +#include "llwearable.h" #include "lltexlayerparams.h" #include "llui.h" //----------------------------------------------------------------------------- // LLTexLayerParam //----------------------------------------------------------------------------- -LLTexLayerParam::LLTexLayerParam(LLTexLayer *layer) : +LLTexLayerParam::LLTexLayerParam(LLTexLayerInterface *layer) : mTexLayer(layer), mAvatar(NULL) { @@ -47,6 +48,10 @@ LLTexLayerParam::LLTexLayerParam(LLTexLayer *layer) : { mAvatar = mTexLayer->getTexLayerSet()->getAvatar(); } + else + { + llerrs << "LLTexLayerParam constructor passed with NULL reference for layer!" << llendl; + } } LLTexLayerParam::LLTexLayerParam(LLVOAvatar *avatar) : @@ -56,15 +61,19 @@ LLTexLayerParam::LLTexLayerParam(LLVOAvatar *avatar) : } -BOOL LLTexLayerParam::setInfo(LLViewerVisualParamInfo *info) +BOOL LLTexLayerParam::setInfo(LLViewerVisualParamInfo *info, BOOL add_to_avatar ) { LLViewerVisualParam::setInfo(info); - mAvatar->addVisualParam( this); + + if (add_to_avatar) + { + mAvatar->addVisualParam( this); + } + return TRUE; } - //----------------------------------------------------------------------------- // LLTexLayerParamAlpha //----------------------------------------------------------------------------- @@ -102,7 +111,7 @@ void LLTexLayerParamAlpha::getCacheByteCount(S32* gl_bytes) } } -LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLTexLayer* layer) : +LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLTexLayerInterface* layer) : LLTexLayerParam(layer), mCachedProcessedTexture(NULL), mNeedsCreateTexture(FALSE), @@ -131,6 +140,13 @@ LLTexLayerParamAlpha::~LLTexLayerParamAlpha() sInstances.remove(this); } +/*virtual*/ LLViewerVisualParam * LLTexLayerParamAlpha::cloneParam(LLWearable* wearable) const +{ + LLTexLayerParamAlpha *new_param = new LLTexLayerParamAlpha(mTexLayer); + *new_param = *this; + return new_param; +} + void LLTexLayerParamAlpha::deleteCaches() { mStaticImageTGA = NULL; // deletes image @@ -313,7 +329,7 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height) // 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()) + if (!mAvatar->isSelf()) { mCachedProcessedTexture = NULL; } @@ -377,7 +393,7 @@ BOOL LLTexLayerParamAlphaInfo::parseXml(LLXmlTreeNode* node) -LLTexLayerParamColor::LLTexLayerParamColor(LLTexLayer* layer) : +LLTexLayerParamColor::LLTexLayerParamColor(LLTexLayerInterface* layer) : LLTexLayerParam(layer), mAvgDistortionVec(1.f, 1.f, 1.f) { @@ -393,6 +409,13 @@ LLTexLayerParamColor::~LLTexLayerParamColor() { } +/*virtual*/ LLViewerVisualParam * LLTexLayerParamColor::cloneParam(LLWearable* wearable) const +{ + LLTexLayerParamColor *new_param = new LLTexLayerParamColor(mTexLayer); + *new_param = *this; + return new_param; +} + LLColor4 LLTexLayerParamColor::getNetColor() const { const LLTexLayerParamColorInfo *info = (LLTexLayerParamColorInfo *)getInfo(); diff --git a/indra/newview/lltexlayerparams.h b/indra/newview/lltexlayerparams.h index 49feb01b5e..589bd41054 100644 --- a/indra/newview/lltexlayerparams.h +++ b/indra/newview/lltexlayerparams.h @@ -36,15 +36,18 @@ class LLTexLayer; class LLVOAvatar; +class LLWearable; class LLTexLayerParam : public LLViewerVisualParam { public: - LLTexLayerParam(LLTexLayer *layer); + LLTexLayerParam(LLTexLayerInterface *layer); LLTexLayerParam(LLVOAvatar *avatar); - /* Virtual */ BOOL setInfo(LLViewerVisualParamInfo *info); + /* Virtual */ BOOL setInfo(LLViewerVisualParamInfo *info, BOOL add_to_avatar ); + /*virtual*/ LLViewerVisualParam * cloneParam(LLWearable* wearable) const = 0; + protected: - LLTexLayer* mTexLayer; + LLTexLayerInterface* mTexLayer; LLVOAvatar* mAvatar; }; @@ -54,10 +57,12 @@ protected: class LLTexLayerParamAlpha : public LLTexLayerParam { public: - LLTexLayerParamAlpha( LLTexLayer* layer ); + LLTexLayerParamAlpha( LLTexLayerInterface* layer ); LLTexLayerParamAlpha( LLVOAvatar* avatar ); /*virtual*/ ~LLTexLayerParamAlpha(); + /*virtual*/ LLViewerVisualParam * cloneParam(LLWearable* wearable = NULL) const; + // LLVisualParam Virtual functions ///*virtual*/ BOOL parseData(LLXmlTreeNode* node); /*virtual*/ void apply( ESex avatar_sex ) {} @@ -129,10 +134,12 @@ public: OP_COUNT = 3 // Number of operations }; - LLTexLayerParamColor( LLTexLayer* layer ); + LLTexLayerParamColor( LLTexLayerInterface* layer ); LLTexLayerParamColor( LLVOAvatar* avatar ); /* virtual */ ~LLTexLayerParamColor(); + /*virtual*/ LLViewerVisualParam * cloneParam(LLWearable* wearable = NULL) const; + // LLVisualParam Virtual functions ///*virtual*/ BOOL parseData(LLXmlTreeNode* node); /*virtual*/ void apply( ESex avatar_sex ) {} diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index 86b162247a..0c23947a8c 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -36,178 +36,106 @@ #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; +const S32 BUTTON_WIDTH = 90; //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; +LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification) : +LLToastPanel(notification), +mTextBox(NULL), +mIcon(NULL), +mInfoPanel(NULL), +mControlPanel(NULL), +mNumOptions(0), +mNumButtons(0), +mAddedDefaultBtn(false) +{ + LLUICtrlFactory::getInstance()->buildPanel(this, "panel_notification.xml"); + mInfoPanel = getChild<LLPanel>("info_panel"); + mControlPanel = getChild<LLPanel>("control_panel"); + mIcon = getChild<LLIconCtrl>("info_icon"); - // clicking on a button does not steal current focus - setIsChrome(TRUE); + // customize panel's attributes + // is it intended for displaying a tip + mIsTip = notification->getType() == "notifytip"; + // is it a script dialog + mIsScriptDialog = (notification->getName() == "ScriptDialog" || notification->getName() == "ScriptDialogGroup"); + // is it a caution + // + // 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; - // class init + // setup parameters + // get a notification message + mMessage = notification->getMessage(); + // init font variables if (!sFont) { sFont = LLFontGL::getFontSansSerif(); sFontSmall = LLFontGL::getFontSansSerifSmall(); } - - // setup paramaters - mMessage = notification->getMessage(); - + // clicking on a button does not steal current focus + setIsChrome(TRUE); // 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; - + // get a form for the notification LLNotificationFormPtr form(notification->getForm()); - + // get number of elements 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); + // customize panel's outfit + // preliminary adjust panel's layout + mIsTip ? adjustPanelForTipNotice() : adjustPanelForScriptNotice(form); + // choose a right icon if (mIsTip) { // use the tip notification icon - common_params.image(LLUI::getUIImage("notify_tip_icon.tga")); - icon = LLUICtrlFactory::create<LLIconCtrl> (common_params); + mIcon->setValue("notify_tip_icon.tga"); + LLRect icon_rect = mIcon->getRect(); + icon_rect.setLeftTopAndSize(icon_rect.mLeft, getRect().getHeight() - VPAD, icon_rect.getWidth(), icon_rect.getHeight()); + mIcon->setRect(icon_rect); } else if (mIsCaution) { // use the caution notification icon - common_params.image(LLUI::getUIImage("notify_caution_icon.tga")); - icon = LLUICtrlFactory::create<LLIconCtrl> (common_params); + mIcon->setValue("notify_caution_icon.tga"); } else { // use the default notification icon - common_params.image(LLUI::getUIImage("notify_box_icon.tga")); - icon = LLUICtrlFactory::create<LLIconCtrl> (common_params); + mIcon->setValue("notify_box_icon.tga"); } - icon->setMouseOpaque(FALSE); - addChild(icon); - - x += HPAD + HPAD + 32; - + // adjust text options according to the notification type // 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.bg_readonly_color(LLUIColorTable::instance().getColor("NotifyCautionBoxColor")); - params.border_visible(false); - params.wrap(true); - caution_box = LLUICtrlFactory::create<LLTextBox> (params); - caution_box->setValue(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; + mTextBox = getChild<LLTextBox>("caution_text_box"); } 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.read_only(true); - params.default_text(mMessage); - params.font(sFont); - params.embedded_items(false); - params.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.border_visible(false); - text = LLUICtrlFactory::create<LLTextEditor> (params); - addChild(text); + mTextBox = getChild<LLTextEditor>("text_editor_box"); } - 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()); + // *TODO: magic numbers(???) - copied from llnotify.cpp(250) + const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE; + + mTextBox->setVisible(TRUE); + mTextBox->setValue(notification->getMessage()); + // add buttons for a script notification + if (!mIsTip) + { for (S32 i = 0; i < mNumOptions; i++) { - LLSD form_element = form->getElement(i); if (form_element["type"].asString() != "button") { @@ -222,137 +150,63 @@ LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification) : LLToas addButton("OK", LLTrans::getString("ok"), FALSE, TRUE); mAddedDefaultBtn = true; } - - } + + // adjust panel's height to the text size + mInfoPanel->setFollowsAll(); + snapToMessageHeight(mTextBox, MAX_LENGTH); } -LLToastNotifyPanel::~LLToastNotifyPanel() { +LLToastNotifyPanel::~LLToastNotifyPanel() +{ std::for_each(mBtnCallbackData.begin(), mBtnCallbackData.end(), DeletePointer()); } -LLRect LLToastNotifyPanel::getNotifyRect(S32 num_options, BOOL mIsScriptDialog, BOOL is_caution) +void LLToastNotifyPanel::adjustPanelForScriptNotice(const LLNotificationFormPtr form) { - S32 notify_height = gSavedSettings.getS32("NotifyBoxHeight"); - if (is_caution) + F32 buttons_num = 0; + S32 button_rows = 0; + + // calculate number of buttons + for (S32 i = 0; i < mNumOptions; i++) { - // 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"); + if (form->getElement(i)["type"].asString() == "button") + { + buttons_num++; + } } - 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) + // calculate necessary height for the button panel + // if notification form contains no buttons - reserve a place for OK button + // script notifications have extra line for an IGNORE button + if(mIsScriptDialog) { - num_options = 1; + button_rows = llceil((buttons_num - 1) / 3.0f) + 1; } - - // Add two "blank" option spaces. - if (mIsScriptDialog) + else { - num_options += 2; + button_rows = llmax( 1, llceil(buttons_num / 3.0f)); } - S32 additional_lines = (num_options-1) / 3; - - notify_height += additional_lines * (BTN_HEIGHT + VPAD); + S32 button_panel_height = button_rows * BTN_HEIGHT + (button_rows + 1) * VPAD + BOTTOM_PAD; - return LLRect(LEFT, TOP, RIGHT, TOP-notify_height); + //adjust layout + LLRect button_rect = mControlPanel->getRect(); + reshape(getRect().getWidth(), mInfoPanel->getRect().getHeight() + button_panel_height); + mControlPanel->reshape(button_rect.getWidth(), button_panel_height); } // static -LLRect LLToastNotifyPanel::getNotifyTipRect(const std::string &utf8message) +void LLToastNotifyPanel::adjustPanelForTipNotice() { - 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 ); + LLRect info_rect = mInfoPanel->getRect(); + LLRect this_rect = getRect(); - 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); + mControlPanel->setVisible(FALSE); + reshape(getRect().getWidth(), mInfoPanel->getRect().getHeight()); } - // static void LLToastNotifyPanel::onClickButton(void* data) { @@ -371,10 +225,6 @@ void LLToastNotifyPanel::onClickButton(void* data) // 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; @@ -397,9 +247,9 @@ LLButton* LLToastNotifyPanel::addButton(const std::string& name, const std::stri } } - btn_rect.setOriginAndSize(x + (index % 3) * (btn_width+HPAD+HPAD) + ignore_pad, + btn_rect.setOriginAndSize(x + (index % 3) * (BUTTON_WIDTH+HPAD+HPAD) + ignore_pad, BOTTOM_PAD + (index / 3) * (BTN_HEIGHT+VPAD), - btn_width - 2*ignore_pad, + BUTTON_WIDTH - 2*ignore_pad, btn_height); InstanceAndS32* userdata = new InstanceAndS32; @@ -422,7 +272,7 @@ LLButton* LLToastNotifyPanel::addButton(const std::string& name, const std::stri btn = LLUICtrlFactory::create<LLButton>(p); - addChild(btn, -1); + mControlPanel->addChild(btn, -1); if (is_default) { diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h index df58c06f25..66534edcdf 100644 --- a/indra/newview/lltoastnotifypanel.h +++ b/indra/newview/lltoastnotifypanel.h @@ -38,6 +38,9 @@ #include "llnotifications.h" #include "llbutton.h" #include "lltoastpanel.h" +#include "lliconctrl.h" +#include "lltexteditor.h" +#include "lltextbox.h" /** @@ -46,15 +49,15 @@ * * Replaces class LLNotifyBox. */ -class LLToastNotifyPanel: public LLToastPanel { +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 { @@ -65,16 +68,23 @@ protected: 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); + void adjustPanelForScriptNotice(const LLNotificationFormPtr form); + void adjustPanelForTipNotice(); + + // panel elements + LLTextBase* mTextBox; + LLIconCtrl* mIcon; + LLPanel* mInfoPanel; // a panel, that contains an information + LLPanel* mControlPanel; // a panel, that contains buttons (if present) + // internal handler for button being clicked static void onClickButton(void* data); + bool mIsTip; bool mAddedDefaultBtn; bool mIsScriptDialog; - bool mIsCaution; // is this a caution notification? + bool mIsCaution; + std::string mMessage; S32 mNumOptions; S32 mNumButtons; diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp index 7b477470aa..ef75e06047 100644 --- a/indra/newview/lltoastpanel.cpp +++ b/indra/newview/lltoastpanel.cpp @@ -34,6 +34,9 @@ #include "lltoastpanel.h" +//static +const S32 LLToastPanel::MIN_PANEL_HEIGHT = 40; // VPAD(4)*2 + ICON_HEIGHT(32) + LLToastPanel::LLToastPanel(LLNotificationPtr& notification) { mNotification = notification; @@ -50,8 +53,13 @@ std::string LLToastPanel::getTitle() } //snap to the message height if it is visible -void LLToastPanel::snapToMessageHeight(LLTextBox* message, S32 maxLineCount) +void LLToastPanel::snapToMessageHeight(LLTextBase* message, S32 maxLineCount) { + if(!message) + { + return; + } + //Add message height if it is visible if (message->getVisible()) { @@ -61,22 +69,16 @@ void LLToastPanel::snapToMessageHeight(LLTextBox* message, S32 maxLineCount) LLRect messageRect = message->getRect(); S32 oldTextHeight = messageRect.getHeight(); - //Reshape the toast to give the message max height. - //This needed to calculate lines count according to specified text - heightDelta = maxTextHeight - oldTextHeight; - reshape( getRect().getWidth(), getRect().getHeight() + heightDelta); - //Knowing the height is set to max allowed, getTextPixelHeight returns needed text height //Perhaps we need to pass maxLineCount as parameter to getTextPixelHeight to avoid previous reshape. - S32 requiredTextHeight = message->getTextPixelHeight(); + S32 requiredTextHeight = message->getContentsRect().getHeight(); S32 newTextHeight = llmin(requiredTextHeight, maxTextHeight); //Calculate last delta height deducting previous heightDelta heightDelta = newTextHeight - oldTextHeight - heightDelta; //reshape the panel with new height - reshape( getRect().getWidth(), getRect().getHeight() + heightDelta); + reshape( getRect().getWidth(), llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT)); } - } diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h index 418373e8c6..a88127b008 100644 --- a/indra/newview/lltoastpanel.h +++ b/indra/newview/lltoastpanel.h @@ -58,9 +58,11 @@ public: virtual std::string getTitle(); virtual const LLUUID& getID() { return mNotification->id();} + + static const S32 MIN_PANEL_HEIGHT; protected: LLNotificationPtr mNotification; - void snapToMessageHeight(LLTextBox* message, S32 maxLineCount); + void snapToMessageHeight(LLTextBase* message, S32 maxLineCount); }; #endif /* LL_TOASTPANEL_H */ diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index e7a8ad6605..841902f683 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -36,7 +36,6 @@ // viewer includes #include "llagent.h" // teleportViaLocation() #include "llcommandhandler.h" -#include "llfloaterdirectory.h" #include "llfloaterhelpbrowser.h" #include "llfloaterreg.h" #include "llfloaterurldisplay.h" diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 22081f9efa..81917ec76e 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -57,7 +57,7 @@ #include "llfloaterchat.h" #include "llfloaterchatterbox.h" #include "llfloaterdaycycle.h" -#include "llfloaterdirectory.h" +#include "llfloatersearch.h" #include "llfloaterenvsettings.h" #include "llfloaterfonttest.h" #include "llfloatergesture.h" @@ -109,6 +109,7 @@ #include "llfloaterwindlight.h" #include "llfloaterworldmap.h" #include "llinspectavatar.h" +#include "llinspectgroup.h" #include "llinspectobject.h" #include "llmediaremotectrl.h" #include "llmoveview.h" @@ -172,6 +173,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("inventory", "floater_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInventory>); LLFloaterReg::add("inspect", "floater_inspect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInspect>); LLInspectAvatarUtil::registerFloater(); + LLInspectGroupUtil::registerFloater(); LLInspectObjectUtil::registerFloater(); LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>); @@ -230,7 +232,7 @@ void LLViewerFloaterReg::registerFloaters() 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("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>); - LLFloaterReg::add("search", "floater_directory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDirectory>); + LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>); LLFloaterUIPreviewUtil::registerFloater(); LLFloaterReg::add("upload_anim", "floater_animation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAnimPreview>, "upload"); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index dc53358311..7e88320f49 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -54,6 +54,7 @@ #include "llviewerwindow.h" #include "lltrans.h" #include "llappearancemgr.h" +#include "llfloatercustomize.h" ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs @@ -611,9 +612,9 @@ void LLViewerInventoryCategory::determineFolderType() const LLViewerInventoryItem *item = (*item_iter); if (item->getIsLinkType()) return; - if (item->getInventoryType() == LLInventoryType::IT_WEARABLE) + if (item->isWearableType()) { - const EWearableType wearable_type = EWearableType(item->getFlags() & LLInventoryItem::II_FLAGS_WEARABLES_MASK); + const EWearableType wearable_type = item->getWearableType(); const std::string& wearable_name = LLWearableDictionary::getTypeName(wearable_type); U64 valid_folder_types = LLFolderType::lookupValidFolderTypes(wearable_name); folder_valid |= valid_folder_types; @@ -729,6 +730,14 @@ void WearOnAvatarCallback::fire(const LLUUID& inv_item) void ModifiedCOFCallback::fire(const LLUUID& inv_item) { LLAppearanceManager::instance().updateAppearanceFromCOF(); + if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode() ) + { + // If we're in appearance editing mode, the current tab may need to be refreshed + if (gFloaterCustomize) + { + gFloaterCustomize->switchToDefaultSubpart(); + } + } } RezAttachmentCallback::RezAttachmentCallback(LLViewerJointAttachment *attachmentp) @@ -1269,6 +1278,22 @@ U32 LLViewerInventoryItem::getFlags() const return LLInventoryItem::getFlags(); } +bool LLViewerInventoryItem::isWearableType() const +{ + return (getInventoryType() == LLInventoryType::IT_WEARABLE); +} + +EWearableType LLViewerInventoryItem::getWearableType() const +{ + if (!isWearableType()) + { + llwarns << "item is not a wearable" << llendl; + return WT_INVALID; + } + return EWearableType(getFlags() & LLInventoryItem::II_FLAGS_WEARABLES_MASK); +} + + time_t LLViewerInventoryItem::getCreationDate() const { return LLInventoryItem::getCreationDate(); diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 5692875ec6..f55a695652 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -74,6 +74,8 @@ public: virtual const std::string& getDescription() const; virtual const LLSaleInfo& getSaleInfo() const; virtual LLInventoryType::EType getInventoryType() const; + virtual bool isWearableType() const; + virtual EWearableType getWearableType() const; virtual U32 getFlags() const; virtual time_t getCreationDate() const; virtual U32 getCRC32() const; // really more of a checksum. diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp index 63c63e5546..2b4b78d82d 100644 --- a/indra/newview/llviewerjointattachment.cpp +++ b/indra/newview/llviewerjointattachment.cpp @@ -57,14 +57,14 @@ extern LLPipeline gPipeline; // LLViewerJointAttachment() //----------------------------------------------------------------------------- LLViewerJointAttachment::LLViewerJointAttachment() : -mAttachedObject(NULL), -mVisibleInFirst(FALSE), -mGroup(0), -mIsHUDAttachment(FALSE), -mPieSlice(-1) + mVisibleInFirst(FALSE), + mGroup(0), + mIsHUDAttachment(FALSE), + mPieSlice(-1) { mValid = FALSE; mUpdateXform = FALSE; + mAttachedObjects.clear(); } //----------------------------------------------------------------------------- @@ -103,36 +103,43 @@ U32 LLViewerJointAttachment::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_ return 0; } -void LLViewerJointAttachment::setupDrawable(LLDrawable* drawablep) +void LLViewerJointAttachment::setupDrawable(LLViewerObject *object) { - drawablep->mXform.setParent(&mXform); // LLViewerJointAttachment::lazyAttach - drawablep->makeActive(); - LLVector3 current_pos = mAttachedObject->getRenderPosition(); - LLQuaternion current_rot = mAttachedObject->getRenderRotation(); - LLQuaternion attachment_pt_inv_rot = ~getWorldRotation(); + if (!object->mDrawable) + return; + if (object->mDrawable->isActive()) + { + object->mDrawable->makeStatic(FALSE); + } + + object->mDrawable->mXform.setParent(getXform()); // LLViewerJointAttachment::lazyAttach + object->mDrawable->makeActive(); + LLVector3 current_pos = object->getRenderPosition(); + LLQuaternion current_rot = object->getRenderRotation(); + LLQuaternion attachment_pt_inv_rot = ~(getWorldRotation()); current_pos -= getWorldPosition(); current_pos.rotVec(attachment_pt_inv_rot); current_rot = current_rot * attachment_pt_inv_rot; - drawablep->mXform.setPosition(current_pos); - drawablep->mXform.setRotation(current_rot); - gPipeline.markMoved(drawablep); - gPipeline.markTextured(drawablep); // face may need to change draw pool to/from POOL_HUD - drawablep->setState(LLDrawable::USE_BACKLIGHT); + object->mDrawable->mXform.setPosition(current_pos); + object->mDrawable->mXform.setRotation(current_rot); + gPipeline.markMoved(object->mDrawable); + gPipeline.markTextured(object->mDrawable); // face may need to change draw pool to/from POOL_HUD + object->mDrawable->setState(LLDrawable::USE_BACKLIGHT); if(mIsHUDAttachment) { - for (S32 face_num = 0; face_num < drawablep->getNumFaces(); face_num++) + for (S32 face_num = 0; face_num < object->mDrawable->getNumFaces(); face_num++) { - drawablep->getFace(face_num)->setState(LLFace::HUD_RENDER); + object->mDrawable->getFace(face_num)->setState(LLFace::HUD_RENDER); } } - LLViewerObject::const_child_list_t& child_list = mAttachedObject->getChildren(); + LLViewerObject::const_child_list_t& child_list = object->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++) + iter != child_list.end(); ++iter) { LLViewerObject* childp = *iter; if (childp && childp->mDrawable.notNull()) @@ -157,27 +164,13 @@ void LLViewerJointAttachment::setupDrawable(LLDrawable* drawablep) //----------------------------------------------------------------------------- BOOL LLViewerJointAttachment::addObject(LLViewerObject* object) { - if (mAttachedObject) + if (isObjectAttached(object)) { - llwarns << "Attempted to attach object where an attachment already exists!" << llendl; - - if (mAttachedObject == object) { - llinfos << "(same object re-attached)" << llendl; - removeObject(mAttachedObject); - // Pass through anyway to let setupDrawable() - // re-connect object to the joint correctly - } - else { - llinfos << "(objects differ, removing existing object)" << llendl; - // Rather hacky, but no-one can think of something - // better to do for this case. - gObjectList.killObject(mAttachedObject); - // Proceed with new object attachment - } + llinfos << "(same object re-attached)" << llendl; + removeObject(object); + // Pass through anyway to let setupDrawable() + // re-connect object to the joint correctly } - mAttachedObject = object; - - LLUUID item_id; // Find the inventory item ID of the attached object LLNameValue* item_id_nv = object->getNVPair("AttachItemID"); @@ -186,26 +179,15 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object) const char* s = item_id_nv->getString(); if( s ) { - item_id.set( s ); + LLUUID item_id; + item_id.set(s); + object->setItemID(item_id); lldebugs << "getNVPair( AttachItemID ) = " << item_id << llendl; } } - - mItemID = item_id; - - LLDrawable* drawablep = object->mDrawable; - - if (drawablep) - { - //if object is active, make it static - if(drawablep->isActive()) - { - drawablep->makeStatic(FALSE) ; - } - - setupDrawable(drawablep); - } - + mAttachedObjects.push_back(object); + setupDrawable(object); + if (mIsHUDAttachment) { if (object->mText.notNull()) @@ -214,7 +196,7 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object) } LLViewerObject::const_child_list_t& child_list = object->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++) + iter != child_list.end(); ++iter) { LLViewerObject* childp = *iter; if (childp && childp->mText.notNull()) @@ -234,15 +216,33 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object) //----------------------------------------------------------------------------- void LLViewerJointAttachment::removeObject(LLViewerObject *object) { + attachedobjs_vec_t::iterator iter; + for (iter = mAttachedObjects.begin(); + iter != mAttachedObjects.end(); + ++iter) + { + LLViewerObject *attached_object = (*iter); + if (attached_object == object) + { + break; + } + } + if (iter == mAttachedObjects.end()) + { + llwarns << "Could not find object to detach" << llendl; + return; + } + // force object visibile setAttachmentVisibility(TRUE); + mAttachedObjects.erase(iter); if (object->mDrawable.notNull()) { //if object is active, make it static if(object->mDrawable->isActive()) { - object->mDrawable->makeStatic(FALSE) ; + object->mDrawable->makeStatic(FALSE); } LLVector3 cur_position = object->getRenderPosition(); @@ -265,7 +265,7 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object) LLViewerObject::const_child_list_t& child_list = object->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++) + iter != child_list.end(); ++iter) { LLViewerObject* childp = *iter; if (childp && childp->mDrawable.notNull()) @@ -290,7 +290,7 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object) } LLViewerObject::const_child_list_t& child_list = object->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++) + iter != child_list.end(); ++iter) { LLViewerObject* childp = *iter; if (childp->mText.notNull()) @@ -299,10 +299,11 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object) } } } - - mAttachedObject = NULL; - mUpdateXform = FALSE; - mItemID.setNull(); + if (mAttachedObjects.size() == 0) + { + mUpdateXform = FALSE; + } + object->setItemID(LLUUID::null); } //----------------------------------------------------------------------------- @@ -310,20 +311,26 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object) //----------------------------------------------------------------------------- void LLViewerJointAttachment::setAttachmentVisibility(BOOL visible) { - if (!mAttachedObject || mAttachedObject->mDrawable.isNull() || - !(mAttachedObject->mDrawable->getSpatialBridge())) - return; - - if (visible) - { - // Hack to make attachments not visible by disabling their type mask! - // This will break if you can ever attach non-volumes! - djs 02/14/03 - mAttachedObject->mDrawable->getSpatialBridge()->mDrawableType = - mAttachedObject->isHUDAttachment() ? LLPipeline::RENDER_TYPE_HUD : LLPipeline::RENDER_TYPE_VOLUME; - } - else + for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin(); + iter != mAttachedObjects.end(); + ++iter) { - mAttachedObject->mDrawable->getSpatialBridge()->mDrawableType = 0; + LLViewerObject *attached_obj = (*iter); + if (!attached_obj || attached_obj->mDrawable.isNull() || + !(attached_obj->mDrawable->getSpatialBridge())) + continue; + + if (visible) + { + // Hack to make attachments not visible by disabling their type mask! + // This will break if you can ever attach non-volumes! - djs 02/14/03 + attached_obj->mDrawable->getSpatialBridge()->mDrawableType = + attached_obj->isHUDAttachment() ? LLPipeline::RENDER_TYPE_HUD : LLPipeline::RENDER_TYPE_VOLUME; + } + else + { + attached_obj->mDrawable->getSpatialBridge()->mDrawableType = 0; + } } } @@ -341,14 +348,19 @@ void LLViewerJointAttachment::setOriginalPosition(LLVector3& position) //----------------------------------------------------------------------------- void LLViewerJointAttachment::clampObjectPosition() { - if (mAttachedObject) + for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin(); + iter != mAttachedObjects.end(); + ++iter) { - // *NOTE: object can drift when hitting maximum radius - LLVector3 attachmentPos = mAttachedObject->getPosition(); - F32 dist = attachmentPos.normVec(); - dist = llmin(dist, MAX_ATTACHMENT_DIST); - attachmentPos *= dist; - mAttachedObject->setPosition(attachmentPos); + if (LLViewerObject *attached_object = (*iter)) + { + // *NOTE: object can drift when hitting maximum radius + LLVector3 attachmentPos = attached_object->getPosition(); + F32 dist = attachmentPos.normVec(); + dist = llmin(dist, MAX_ATTACHMENT_DIST); + attachmentPos *= dist; + attached_object->setPosition(attachmentPos); + } } } @@ -357,14 +369,23 @@ void LLViewerJointAttachment::clampObjectPosition() //----------------------------------------------------------------------------- void LLViewerJointAttachment::calcLOD() { - F32 maxarea = mAttachedObject->getMaxScale() * mAttachedObject->getMidScale(); - LLViewerObject::const_child_list_t& child_list = mAttachedObject->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++) + F32 maxarea = 0; + for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin(); + iter != mAttachedObjects.end(); + ++iter) { - LLViewerObject* childp = *iter; - F32 area = childp->getMaxScale() * childp->getMidScale(); - maxarea = llmax(maxarea, area); + if (LLViewerObject *attached_object = (*iter)) + { + maxarea = llmax(maxarea,attached_object->getMaxScale() * attached_object->getMidScale()); + LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + LLViewerObject* childp = *iter; + F32 area = childp->getMaxScale() * childp->getMidScale(); + maxarea = llmax(maxarea, area); + } + } } maxarea = llclamp(maxarea, .01f*.01f, 1.f); F32 avatar_area = (4.f * 4.f); // pixels for an avatar sized attachment @@ -386,3 +407,47 @@ BOOL LLViewerJointAttachment::updateLOD(F32 pixel_area, BOOL activate) return res; } +BOOL LLViewerJointAttachment::isObjectAttached(const LLViewerObject *viewer_object) const +{ + for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin(); + iter != mAttachedObjects.end(); + ++iter) + { + const LLViewerObject* attached_object = (*iter); + if (attached_object == viewer_object) + { + return TRUE; + } + } + return FALSE; +} + +const LLViewerObject *LLViewerJointAttachment::getAttachedObject(const LLUUID &object_id) const +{ + for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin(); + iter != mAttachedObjects.end(); + ++iter) + { + const LLViewerObject* attached_object = (*iter); + if (attached_object->getItemID() == object_id) + { + return attached_object; + } + } + return NULL; +} + +LLViewerObject *LLViewerJointAttachment::getAttachedObject(const LLUUID &object_id) +{ + for (attachedobjs_vec_t::iterator iter = mAttachedObjects.begin(); + iter != mAttachedObjects.end(); + ++iter) + { + LLViewerObject* attached_object = (*iter); + if (attached_object->getItemID() == object_id) + { + return attached_object; + } + } + return NULL; +} diff --git a/indra/newview/llviewerjointattachment.h b/indra/newview/llviewerjointattachment.h index c003579684..221b5460f1 100644 --- a/indra/newview/llviewerjointattachment.h +++ b/indra/newview/llviewerjointattachment.h @@ -82,9 +82,9 @@ public: 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; } + S32 getNumObjects() const { return mAttachedObjects.size(); } + + void clampObjectPosition(); // // unique methods @@ -92,21 +92,27 @@ public: BOOL addObject(LLViewerObject* object); void removeObject(LLViewerObject *object); - void setupDrawable(LLDrawable* drawable); - void clampObjectPosition(); + // + // attachments operations + // + BOOL isObjectAttached(const LLViewerObject *viewer_object) const; + const LLViewerObject *getAttachedObject(const LLUUID &object_id) const; + LLViewerObject *getAttachedObject(const LLUUID &object_id); + + // list of attachments for this joint + typedef std::vector<LLViewerObject *> attachedobjs_vec_t; + attachedobjs_vec_t mAttachedObjects; protected: void calcLOD(); - -protected: - // Backlink only; don't make this an LLPointer. - LLViewerObject* mAttachedObject; + void setupDrawable(LLViewerObject *object); + +private: BOOL mVisibleInFirst; LLVector3 mOriginalPos; S32 mGroup; BOOL mIsHUDAttachment; S32 mPieSlice; - LLUUID mItemID; // Inventory item id of the attached item (null if not in inventory) }; #endif // LL_LLVIEWERJOINTATTACHMENT_H diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index b8cf3e667e..c9bfc1d296 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1024,7 +1024,14 @@ void LLViewerMediaImpl::navigateBack() { if(mMediaSource->pluginSupportsMediaTime()) { - mMediaSource->start(-2.0); + F64 step_scale = 0.02; // temp , can be changed + F64 back_step = mMediaSource->getCurrentTime() - (mMediaSource->getDuration()*step_scale); + if(back_step < 0.0) + { + back_step = 0.0; + } + mMediaSource->seek(back_step); + //mMediaSource->start(-2.0); } else { @@ -1040,7 +1047,14 @@ void LLViewerMediaImpl::navigateForward() { if(mMediaSource->pluginSupportsMediaTime()) { - mMediaSource->start(2.0); + F64 step_scale = 0.02; // temp , can be changed + F64 forward_step = mMediaSource->getCurrentTime() + (mMediaSource->getDuration()*step_scale); + if(forward_step > mMediaSource->getDuration()) + { + forward_step = mMediaSource->getDuration(); + } + mMediaSource->seek(forward_step); + //mMediaSource->start(2.0); } else { @@ -1509,6 +1523,19 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_COMPLETE: { LL_DEBUGS("Media") << "MEDIA_EVENT_NAVIGATE_COMPLETE, uri is: " << plugin->getNavigateURI() << LL_ENDL; + + if(getNavState() == MEDIANAVSTATE_BEGUN) + { + setNavState(MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED); + } + else if(getNavState() == MEDIANAVSTATE_SERVER_BEGUN) + { + setNavState(MEDIANAVSTATE_SERVER_COMPLETE_BEFORE_LOCATION_CHANGED); + } + else + { + // all other cases need to leave the state alone. + } } break; @@ -1711,9 +1738,11 @@ void LLViewerMediaImpl::setNavState(EMediaNavState state) case MEDIANAVSTATE_NONE: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_NONE" << llendl; break; case MEDIANAVSTATE_BEGUN: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_BEGUN" << llendl; break; case MEDIANAVSTATE_FIRST_LOCATION_CHANGED: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_FIRST_LOCATION_CHANGED" << llendl; break; + case MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED" << llendl; break; case MEDIANAVSTATE_SERVER_SENT: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_SERVER_SENT" << llendl; break; case MEDIANAVSTATE_SERVER_BEGUN: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_SERVER_BEGUN" << llendl; break; case MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED" << llendl; break; + case MEDIANAVSTATE_SERVER_COMPLETE_BEFORE_LOCATION_CHANGED: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_SERVER_COMPLETE_BEFORE_LOCATION_CHANGED" << llendl; break; } } diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 05c67eda47..fc2776ee91 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -243,12 +243,14 @@ public: typedef enum { - MEDIANAVSTATE_NONE, // State is outside what we need to track for navigation. - MEDIANAVSTATE_BEGUN, // a MEDIA_EVENT_NAVIGATE_BEGIN has been received which was not server-directed - MEDIANAVSTATE_FIRST_LOCATION_CHANGED, // first LOCATION_CHANGED event after a non-server-directed BEGIN - MEDIANAVSTATE_SERVER_SENT, // server-directed nav has been requested, but MEDIA_EVENT_NAVIGATE_BEGIN hasn't been received yet - MEDIANAVSTATE_SERVER_BEGUN, // MEDIA_EVENT_NAVIGATE_BEGIN has been received which was server-directed - MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED // first LOCATION_CHANGED event after a server-directed BEGIN + MEDIANAVSTATE_NONE, // State is outside what we need to track for navigation. + MEDIANAVSTATE_BEGUN, // a MEDIA_EVENT_NAVIGATE_BEGIN has been received which was not server-directed + MEDIANAVSTATE_FIRST_LOCATION_CHANGED, // first LOCATION_CHANGED event after a non-server-directed BEGIN + MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED, // we received a NAVIGATE_COMPLETE event before the first LOCATION_CHANGED + MEDIANAVSTATE_SERVER_SENT, // server-directed nav has been requested, but MEDIA_EVENT_NAVIGATE_BEGIN hasn't been received yet + MEDIANAVSTATE_SERVER_BEGUN, // MEDIA_EVENT_NAVIGATE_BEGIN has been received which was server-directed + MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED, // first LOCATION_CHANGED event after a server-directed BEGIN + MEDIANAVSTATE_SERVER_COMPLETE_BEFORE_LOCATION_CHANGED // we received a NAVIGATE_COMPLETE event before the first LOCATION_CHANGED }EMediaNavState; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index bee34dde8f..d61de77f58 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -97,7 +97,6 @@ #include "llfloaterchat.h" #include "llfloatercustomize.h" #include "llfloaterdaycycle.h" -#include "llfloaterdirectory.h" #include "llfloaterchatterbox.h" #include "llfloaterfonttest.h" #include "llfloatergodtools.h" @@ -2809,7 +2808,7 @@ class LLSelfEnableRemoveAllAttachments : public view_listener_t { LLVOAvatar::attachment_map_t::iterator curiter = iter++; LLViewerJointAttachment* attachment = curiter->second; - if (attachment->getObject()) + if (attachment->getNumObjects() > 0) { new_value = true; break; @@ -3066,7 +3065,7 @@ class LLAvatarDebug : public view_listener_t strings.push_back(avatar->getID().asString()); LLUUID invoice; send_generic_message("dumptempassetdata", strings, invoice); - LLFloaterReg::showInstance( "avatar_tetures", LLSD(avatar->getID()) ); + LLFloaterReg::showInstance( "avatar_textures", LLSD(avatar->getID()) ); } return true; } @@ -3516,9 +3515,6 @@ void set_god_level(U8 god_level) gIMMgr->refresh(); LLViewerParcelMgr::getInstance()->notifyObservers(); - // Some classifieds change visibility on god mode - LLFloaterDirectory::requestClassifieds(); - // God mode changes sim visibility LLWorldMap::getInstance()->reset(); LLWorldMap::getInstance()->setCurrentLayer(0); @@ -5900,12 +5896,12 @@ void near_attach_object(BOOL success, void *user_data) { if (success) { - LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data; + const LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data; U8 attachment_id = 0; if (attachment) { - for (LLVOAvatar::attachment_map_t::iterator iter = gAgent.getAvatarObject()->mAttachmentPoints.begin(); + for (LLVOAvatar::attachment_map_t::const_iterator iter = gAgent.getAvatarObject()->mAttachmentPoints.begin(); iter != gAgent.getAvatarObject()->mAttachmentPoints.end(); ++iter) { if (iter->second == attachment) @@ -6005,24 +6001,27 @@ class LLAttachmentDrop : public view_listener_t class LLAttachmentDetachFromPoint : public view_listener_t { bool handleEvent(const LLSD& user_data) -{ - LLViewerJointAttachment *attachment = get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, user_data.asInteger(), (LLViewerJointAttachment*)NULL); - - LLViewerObject* attached_object = attachment ? attachment->getObject() : NULL; - - if (attached_object) { - gMessageSystem->newMessage("ObjectDetach"); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, attached_object->getLocalID()); - gMessageSystem->sendReliable( gAgent.getRegionHost() ); - } + const LLViewerJointAttachment *attachment = get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, user_data.asInteger(), (LLViewerJointAttachment*)NULL); + if (attachment->getNumObjects() > 0) + { + gMessageSystem->newMessage("ObjectDetach"); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + + for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator iter = attachment->mAttachedObjects.begin(); + iter != attachment->mAttachedObjects.end(); + iter++) + { + LLViewerObject *attached_object = (*iter); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, attached_object->getLocalID()); + } + gMessageSystem->sendReliable( gAgent.getRegionHost() ); + } return true; -} + } }; static bool onEnableAttachmentLabel(LLUICtrl* ctrl, const LLSD& data) @@ -6031,25 +6030,31 @@ static bool onEnableAttachmentLabel(LLUICtrl* ctrl, const LLSD& data) LLMenuItemGL* menu = dynamic_cast<LLMenuItemGL*>(ctrl); if (menu) { - LLViewerJointAttachment *attachmentp = get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, data["index"].asInteger(), (LLViewerJointAttachment*)NULL); - if (attachmentp) - { - label = data["label"].asString(); - if (attachmentp->getObject()) + const LLViewerJointAttachment *attachment = get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, data["index"].asInteger(), (LLViewerJointAttachment*)NULL); + if (attachment) { - LLViewerInventoryItem* itemp = gInventory.getItem(attachmentp->getItemID()); - if (itemp) + label = data["label"].asString(); + for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) { - label += std::string(" (") + itemp->getName() + std::string(")"); + const LLViewerObject* attached_object = (*attachment_iter); + if (attached_object) + { + LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getItemID()); + if (itemp) + { + label += std::string(" (") + itemp->getName() + std::string(")"); + break; + } + } } } - } menu->setLabel(label); -} + } return true; } - class LLAttachmentDetach : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -6136,33 +6141,37 @@ class LLAttachmentEnableDrop : public view_listener_t // item is in your inventory LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - LLViewerJointAttachment* attachment_pt = NULL; + LLViewerJointAttachment* attachment = NULL; LLInventoryItem* item = NULL; - if ( object ) + if (object) { S32 attachmentID = ATTACHMENT_ID_FROM_STATE(object->getState()); - attachment_pt = get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL); + attachment = get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL); - if ( attachment_pt ) + if (attachment) { - // make sure item is in your inventory (it could be a delayed attach message being sent from the sim) - // so check to see if the item is in the inventory already - item = gInventory.getItem(attachment_pt->getItemID()); - - if ( !item ) + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) { - // Item does not exist, make an observer to enable the pie menu - // when the item finishes fetching worst case scenario - // if a fetch is already out there (being sent from a slow sim) - // we refetch and there are 2 fetches - LLWornItemFetchedObserver* wornItemFetched = new LLWornItemFetchedObserver(); - LLInventoryFetchObserver::item_ref_t items; //add item to the inventory item to be fetched - - items.push_back(attachment_pt->getItemID()); - - wornItemFetched->fetchItems(items); - gInventory.addObserver(wornItemFetched); + // make sure item is in your inventory (it could be a delayed attach message being sent from the sim) + // so check to see if the item is in the inventory already + item = gInventory.getItem((*attachment_iter)->getItemID()); + if (!item) + { + // Item does not exist, make an observer to enable the pie menu + // when the item finishes fetching worst case scenario + // if a fetch is already out there (being sent from a slow sim) + // we refetch and there are 2 fetches + LLWornItemFetchedObserver* wornItemFetched = new LLWornItemFetchedObserver(); + LLInventoryFetchObserver::item_ref_t items; //add item to the inventory item to be fetched + + items.push_back((*attachment_iter)->getItemID()); + + wornItemFetched->fetchItems(items); + gInventory.addObserver(wornItemFetched); + } } } } @@ -6265,11 +6274,11 @@ class LLAttachmentPointFilled : public view_listener_t 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; + { + enable = found_it->second->getNumObjects() > 0; } return enable; -} + } }; class LLAvatarSendIM : public view_listener_t @@ -6492,17 +6501,23 @@ void handle_dump_attachments(void*) LLVOAvatar::attachment_map_t::iterator curiter = iter++; LLViewerJointAttachment* attachment = curiter->second; S32 key = curiter->first; - BOOL visible = (attachment->getObject() != NULL && - attachment->getObject()->mDrawable.notNull() && - !attachment->getObject()->mDrawable->isRenderType(0)); - LLVector3 pos; - if (visible) pos = attachment->getObject()->mDrawable->getPosition(); - llinfos << "ATTACHMENT " << key << ": item_id=" << attachment->getItemID() - << (attachment->getObject() ? " present " : " absent ") - << (visible ? "visible " : "invisible ") - << " at " << pos - << " and " << (visible ? attachment->getObject()->getPosition() : LLVector3::zero) - << llendl; + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject *attached_object = (*attachment_iter); + BOOL visible = (attached_object != NULL && + attached_object->mDrawable.notNull() && + !attached_object->mDrawable->isRenderType(0)); + LLVector3 pos; + if (visible) pos = attached_object->mDrawable->getPosition(); + llinfos << "ATTACHMENT " << key << ": item_id=" << attached_object->getItemID() + << (attached_object ? " present " : " absent ") + << (visible ? "visible " : "invisible ") + << " at " << pos + << " and " << (visible ? attached_object->getPosition() : LLVector3::zero) + << llendl; + } } } @@ -6913,11 +6928,12 @@ void handle_debug_avatar_textures(void*) void handle_grab_texture(void* data) { - ETextureIndex index = (ETextureIndex)((intptr_t)data); + ETextureIndex tex_index = (ETextureIndex)((intptr_t)data); const LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); if ( avatar ) { - const LLUUID& asset_id = avatar->grabLocalTexture(index); + // MULTI-WEARABLE: change to support an index + const LLUUID& asset_id = avatar->grabLocalTexture(tex_index, 0); LL_INFOS("texture") << "Adding baked texture " << asset_id << " to inventory." << llendl; LLAssetType::EType asset_type = LLAssetType::AT_TEXTURE; LLInventoryType::EType inv_type = LLInventoryType::IT_TEXTURE; @@ -6925,7 +6941,7 @@ void handle_grab_texture(void* data) if(folder_id.notNull()) { std::string name = "Unknown"; - const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(index); + const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(tex_index); if (texture_dict->mIsBakedTexture) { EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; @@ -6992,7 +7008,8 @@ BOOL enable_grab_texture(void* data) const LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); if ( avatar ) { - return avatar->canGrabLocalTexture(index); + // MULTI-WEARABLE: + return avatar->canGrabLocalTexture(index,0); } return FALSE; } diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index aa662b713e..b268413d36 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -95,6 +95,7 @@ #include "llmenugl.h" #include "llmoveview.h" #include "llmutelist.h" +#include "llnearbychat.h" #include "llnotifications.h" #include "llnotify.h" #include "llpanelgrouplandmoney.h" @@ -1986,6 +1987,12 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // IMs from objcts don't open IM sessions. chat.mSourceType = CHAT_SOURCE_OBJECT; LLFloaterChat::addChat(chat, FALSE, FALSE); + + // archive message in nearby chat + LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD()); + if(nearby_chat) + nearby_chat->addMessage(chat); + } break; case IM_FROM_TASK_AS_ALERT: diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 1f4f1322fd..20cd516fa0 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -219,7 +219,8 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mJointInfo(NULL), mState(0), mMedia(NULL), - mClickAction(0) + mClickAction(0), + mAttachmentItemID(LLUUID::null) { if(!is_global) { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index bec36f9da7..b8ae31118c 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -676,6 +676,12 @@ protected: private: static S32 sNumObjects; + +public: + const LLUUID &getItemID() const { return mAttachmentItemID; } + void setItemID(const LLUUID &id) { mAttachmentItemID = id; } +private: + LLUUID mAttachmentItemID; // ItemID when item is in user inventory. }; /////////////////// diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 1d982265ca..2927ca5292 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1216,21 +1216,25 @@ void LLViewerObjectList::generatePickList(LLCamera &camera) iter != avatarp->mAttachmentPoints.end(); ) { LLVOAvatar::attachment_map_t::iterator curiter = iter++; - LLViewerJointAttachment* attachmentp = curiter->second; - if (attachmentp->getIsHUDAttachment()) + LLViewerJointAttachment* attachment = curiter->second; + if (attachment->getIsHUDAttachment()) { - LLViewerObject* objectp = attachmentp->getObject(); - if (objectp) + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) { - mSelectPickList.insert(objectp); - LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++) + if (LLViewerObject* attached_object = (*attachment_iter)) { - LLViewerObject* childp = *iter; - if (childp) + mSelectPickList.insert(attached_object); + LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++) { - mSelectPickList.insert(childp); + LLViewerObject* childp = *iter; + if (childp) + { + mSelectPickList.insert(childp); + } } } } diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 994fbd8475..6e07d8f246 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -52,7 +52,6 @@ #include "llvlmanager.h" #include "llagent.h" #include "llviewercontrol.h" -#include "llfloaterdirectory.h" #include "llfloatertools.h" #include "lldebugview.h" #include "llfasttimerview.h" @@ -813,8 +812,6 @@ void send_stats() S32 window_size = (window_width * window_height) / 1024; misc["string_1"] = llformat("%d", window_size); // misc["string_2"] = -// misc["int_1"] = LLFloaterDirectory::sOldSearchCount; // Steve: 1.18.6 -// misc["int_2"] = LLFloaterDirectory::sNewSearchCount; // Steve: 1.18.6 // misc["int_1"] = LLSD::Integer(gSavedSettings.getU32("RenderQualityPerformance")); // Steve: 1.21 // misc["int_2"] = LLSD::Integer(gFrameStalls); // Steve: 1.21 diff --git a/indra/newview/llviewervisualparam.cpp b/indra/newview/llviewervisualparam.cpp index 7d717ed6dc..b088ef0730 100644 --- a/indra/newview/llviewervisualparam.cpp +++ b/indra/newview/llviewervisualparam.cpp @@ -85,6 +85,12 @@ BOOL LLViewerVisualParamInfo::parseXml(LLXmlTreeNode *node) mEditGroup = ""; } + static LLStdStringHandle cross_wearable_string = LLXmlTree::addAttributeString("cross_wearable"); + if (!node->getFastAttributeBOOL(cross_wearable_string, mCrossWearable)) + { + mCrossWearable = FALSE; + } + // Optional camera offsets from the current joint center. Used for generating "hints" (thumbnails). static LLStdStringHandle camera_distance_string = LLXmlTree::addAttributeString("camera_distance"); node->getFastAttributeF32( camera_distance_string, mCamDist ); @@ -112,6 +118,15 @@ BOOL LLViewerVisualParamInfo::parseXml(LLXmlTreeNode *node) return TRUE; } +/*virtual*/ void LLViewerVisualParamInfo::toStream(std::ostream &out) +{ + LLVisualParamInfo::toStream(out); + + out << mWearableType << "\t"; + out << mEditGroup << "\t"; + out << mEditGroupDisplayOrder << "\t"; +} + //----------------------------------------------------------------------------- // LLViewerVisualParam() //----------------------------------------------------------------------------- diff --git a/indra/newview/llviewervisualparam.h b/indra/newview/llviewervisualparam.h index 77a95db564..82a694e277 100644 --- a/indra/newview/llviewervisualparam.h +++ b/indra/newview/llviewervisualparam.h @@ -37,6 +37,8 @@ #include "llstring.h" #include "llvisualparam.h" +class LLWearable; + //----------------------------------------------------------------------------- // LLViewerVisualParamInfo //----------------------------------------------------------------------------- @@ -49,8 +51,11 @@ public: /*virtual*/ BOOL parseXml(LLXmlTreeNode* node); + /*virtual*/ void toStream(std::ostream &out); + protected: S32 mWearableType; + BOOL mCrossWearable; std::string mEditGroup; F32 mCamDist; F32 mCamAngle; // degrees @@ -77,6 +82,8 @@ public: LLViewerVisualParamInfo *getInfo() const { return (LLViewerVisualParamInfo*)mInfo; }; // This sets mInfo and calls initialization functions BOOL setInfo(LLViewerVisualParamInfo *info); + + virtual LLViewerVisualParam * cloneParam(LLWearable* wearable) const = 0; // LLVisualParam Virtual functions ///*virtual*/ BOOL parseData(LLXmlTreeNode* node); @@ -102,6 +109,8 @@ public: BOOL getShowSimple() const { return getInfo()->mShowSimple; } F32 getSimpleMin() const { return getInfo()->mSimpleMin; } F32 getSimpleMax() const { return getInfo()->mSimpleMax; } + + BOOL getCrossWearable() const { return getInfo()->mCrossWearable; } }; #endif // LL_LLViewerVisualParam_H diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index d81c8eec70..c659e58e47 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2303,7 +2303,9 @@ void LLViewerWindow::handleScrollWheel(S32 clicks) } // Zoom the camera in and out behavior - gAgent.handleScrollWheel(clicks); + + if(top_ctrl == 0 && mWorldViewRect.pointInRect(mCurrentMousePoint.mX, mCurrentMousePoint.mY) ) + gAgent.handleScrollWheel(clicks); return; } @@ -4178,8 +4180,9 @@ void LLViewerWindow::drawMouselookInstructions() instructions, 0, getVirtualWorldViewRect().getCenterX(), getVirtualWorldViewRect().mBottom + INSTRUCTIONS_PAD, - LLColor4( 0.0f, 0.0f, 0.0f, 0.6f ), - LLFontGL::HCENTER, LLFontGL::TOP); + LLColor4( 1.0f, 1.0f, 1.0f, 0.5f ), + LLFontGL::HCENTER, LLFontGL::TOP, + LLFontGL::NORMAL,LLFontGL::DROP_SHADOW); } S32 LLViewerWindow::getWindowHeight() const diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 7c12186bc7..76e00db91c 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -623,7 +623,7 @@ F32 LLVOAvatar::sGreyUpdateTime = 0.f; // Helper functions //----------------------------------------------------------------------------- static F32 calc_bouncy_animation(F32 x); -static U32 calc_shame(LLVOVolume* volume, std::set<LLUUID> &textures); +static U32 calc_shame(const LLVOVolume* volume, std::set<LLUUID> &textures); //----------------------------------------------------------------------------- // LLVOAvatar() @@ -1357,27 +1357,32 @@ void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax) continue ; } - LLViewerObject* object = attachment->getObject(); - if (object && !object->isHUDAttachment()) + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) { - LLDrawable* drawable = object->mDrawable; - if (drawable) + const LLViewerObject* attached_object = (*attachment_iter); + if (attached_object && !attached_object->isHUDAttachment()) { - LLSpatialBridge* bridge = drawable->getSpatialBridge(); - if (bridge) + LLDrawable* drawable = attached_object->mDrawable; + if (drawable) { - const LLVector3* ext = bridge->getSpatialExtents(); - LLVector3 distance = (ext[1] - ext[0]); - - // Only add the prim to spatial extents calculations if it isn't a megaprim. - // max_attachment_span calculated at the start of the function - // (currently 5 times our max prim size) - if (distance.mV[0] < max_attachment_span - && distance.mV[1] < max_attachment_span - && distance.mV[2] < max_attachment_span) + LLSpatialBridge* bridge = drawable->getSpatialBridge(); + if (bridge) { - update_min_max(newMin,newMax,ext[0]); - update_min_max(newMin,newMax,ext[1]); + const LLVector3* ext = bridge->getSpatialExtents(); + LLVector3 distance = (ext[1] - ext[0]); + + // Only add the prim to spatial extents calculations if it isn't a megaprim. + // max_attachment_span calculated at the start of the function + // (currently 5 times our max prim size) + if (distance.mV[0] < max_attachment_span + && distance.mV[1] < max_attachment_span + && distance.mV[2] < max_attachment_span) + { + update_min_max(newMin,newMax,ext[0]); + update_min_max(newMin,newMax,ext[1]); + } } } } @@ -2327,30 +2332,35 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) { attachment_map_t::iterator curiter = iter++; LLViewerJointAttachment* attachment = curiter->second; - LLViewerObject *attached_object = attachment->getObject(); - BOOL visibleAttachment = visible || (attached_object && - !(attached_object->mDrawable->getSpatialBridge() && - attached_object->mDrawable->getSpatialBridge()->getRadius() < 2.0)); - - if (visibleAttachment && attached_object && !attached_object->isDead() && attachment->getValid()) + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) { - // if selecting any attachments, update all of them as non-damped - if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment()) - { - gPipeline.updateMoveNormalAsync(attached_object->mDrawable); - } - else - { - gPipeline.updateMoveDampedAsync(attached_object->mDrawable); - } - - LLSpatialBridge* bridge = attached_object->mDrawable->getSpatialBridge(); - if (bridge) + LLViewerObject* attached_object = (*attachment_iter); + BOOL visibleAttachment = visible || (attached_object && + !(attached_object->mDrawable->getSpatialBridge() && + attached_object->mDrawable->getSpatialBridge()->getRadius() < 2.0)); + + if (visibleAttachment && attached_object && !attached_object->isDead() && attachment->getValid()) { - gPipeline.updateMoveNormalAsync(bridge); + // if selecting any attachments, update all of them as non-damped + if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment()) + { + gPipeline.updateMoveNormalAsync(attached_object->mDrawable); + } + else + { + gPipeline.updateMoveDampedAsync(attached_object->mDrawable); + } + + LLSpatialBridge* bridge = attached_object->mDrawable->getSpatialBridge(); + if (bridge) + { + gPipeline.updateMoveNormalAsync(bridge); + } + attached_object->updateText(); } - attached_object->updateText(); } } } @@ -3548,15 +3558,21 @@ void LLVOAvatar::updateVisibility() { attachment_map_t::iterator curiter = iter++; LLViewerJointAttachment* attachment = curiter->second; - if (attachment->getObject()) + + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) { - if(attachment->getObject()->mDrawable->isVisible()) + if (LLViewerObject *attached_object = (*attachment_iter)) { - llinfos << attachment->getName() << " visible" << llendl; - } - else - { - llinfos << attachment->getName() << " not visible at " << mDrawable->getWorldPosition() << " and radius " << mDrawable->getRadius() << llendl; + if(attached_object->mDrawable->isVisible()) + { + llinfos << attachment->getName() << " visible" << llendl; + } + else + { + llinfos << attachment->getName() << " not visible at " << mDrawable->getWorldPosition() << " and radius " << mDrawable->getRadius() << llendl; + } } } } @@ -3804,7 +3820,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 (getImage(TEX_HAIR_BAKED)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha) + if (getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha) { num_indices += mMeshLOD[MESH_ID_HAIR]->render(mAdjustedPixelArea, first_pass, mIsDummy); first_pass = FALSE; @@ -3965,7 +3981,7 @@ void LLVOAvatar::updateTextures(LLAgent &agent) { if (layer_baked[i] && !mBakedTextureDatas[i].mIsLoaded) { - gGL.getTexUnit(0)->bind(getImage( mBakedTextureDatas[i].mTextureIndex )); + gGL.getTexUnit(0)->bind(getImage( mBakedTextureDatas[i].mTextureIndex, 0 )); } } } @@ -3973,17 +3989,32 @@ void LLVOAvatar::updateTextures(LLAgent &agent) mMaxPixelArea = 0.f; mMinPixelArea = 99999999.f; mHasGrey = FALSE; // debug - for (U32 index = 0; index < getNumTEs(); index++) + for (U32 texture = 0; texture < getNumTEs(); texture++) { - LLViewerFetchedTexture *imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(index), TRUE); - if (imagep) + EWearableType wearable_type = LLVOAvatarDictionary::getTEWearableType((ETextureIndex)texture); + U32 num_wearables = gAgentWearables.getWearableCount(wearable_type); + const LLTextureEntry *te = getTE(texture); + const F32 texel_area_ratio = fabs(te->mScaleS * te->mScaleT); + LLViewerFetchedTexture *imagep = NULL; + for (U32 wearable_index = 0; wearable_index < num_wearables; wearable_index++) + { + imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture, wearable_index), TRUE); + if (imagep) + { + const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture((ETextureIndex)texture); + const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; + if (texture_dict->mIsLocalTexture) + { + addLocalTextureStats((ETextureIndex)texture, imagep, texel_area_ratio, render_avatar, layer_baked[baked_index]); + } + } + } + if (isIndexBakedTexture((ETextureIndex) texture)) { - const LLTextureEntry *te = getTE(index); - const F32 texel_area_ratio = fabs(te->mScaleS * te->mScaleT); const S32 boost_level = getAvatarBakedBoostLevel(); - + imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture,0), TRUE); // Spam if this is a baked texture, not set to default image, without valid host info - if (isIndexBakedTexture((ETextureIndex)index) + if (isIndexBakedTexture((ETextureIndex)texture) && imagep->getID() != IMG_DEFAULT_AVATAR && !imagep->getTargetHost().isOk()) { @@ -3993,25 +4024,7 @@ void LLVOAvatar::updateTextures(LLAgent &agent) << " 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::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture((ETextureIndex)index); - if (texture_dict->mIsUsedByBakedTexture) - { - const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; - if (texture_dict->mIsLocalTexture) - { - addLocalTextureStats((ETextureIndex)index, imagep, texel_area_ratio, render_avatar, layer_baked[baked_index]); - } - else if (texture_dict->mIsBakedTexture) - { - if (layer_baked[baked_index]) - { - addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level ); - } - } - } + addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level ); } } @@ -4044,13 +4057,13 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel } //virtual -void LLVOAvatar::setImage(const U8 te, LLViewerTexture *imagep) +void LLVOAvatar::setImage(const U8 te, LLViewerTexture *imagep, const U32 index) { setTEImage(te, imagep); } //virtual -LLViewerTexture* LLVOAvatar::getImage(const U8 te) const +LLViewerTexture* LLVOAvatar::getImage(const U8 te, const U32 index) const { return getTEImage(te); } @@ -4749,6 +4762,12 @@ BOOL LLVOAvatar::loadAvatar() if (driver_param->setInfo(info)) { addVisualParam( driver_param ); + LLVisualParam*(LLVOAvatar::*avatar_function)(S32)const = &LLVOAvatar::getVisualParam; + if( !driver_param->linkDrivenParams(boost::bind(avatar_function,(LLVOAvatar*)this,_1 ), false)) + { + llwarns << "could not link driven params for avatar " << this->getFullname() << " id: " << driver_param->getID() << llendl; + continue; + } } else { @@ -4757,6 +4776,19 @@ BOOL LLVOAvatar::loadAvatar() return FALSE; } } + + // Uncomment to enable avatar_lad.xml debugging. +/* std::ofstream file; + file.open("avatar_lad.log"); + for( LLViewerVisualParam* param = (LLViewerVisualParam*) getFirstVisualParam(); + param; + param = (LLViewerVisualParam*) getNextVisualParam() ) + { + param->getInfo()->toStream(file); + file << std::endl; + } + + file.close();*/ return TRUE; } @@ -5386,7 +5418,10 @@ void LLVOAvatar::addChild(LLViewerObject *childp) void LLVOAvatar::removeChild(LLViewerObject *childp) { LLViewerObject::removeChild(childp); - detachObject(childp); + if (!detachObject(childp)) + { + llwarns << "Calling detach on non-attached object " << llendl; + } } LLViewerJointAttachment* LLVOAvatar::getTargetAttachmentPoint(LLViewerObject* viewer_object) @@ -5406,7 +5441,7 @@ LLViewerJointAttachment* LLVOAvatar::getTargetAttachmentPoint(LLViewerObject* vi //----------------------------------------------------------------------------- // attachObject() //----------------------------------------------------------------------------- -LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_object) +const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_object) { LLViewerJointAttachment* attachment = getTargetAttachmentPoint(viewer_object); @@ -5425,6 +5460,30 @@ LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_object) } //----------------------------------------------------------------------------- +// attachObject() +//----------------------------------------------------------------------------- +U32 LLVOAvatar::getNumAttachments() const +{ + U32 num_attachments = 0; + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + iter++) + { + const LLViewerJointAttachment *attachment_pt = (*iter).second; + num_attachments += attachment_pt->getNumObjects(); + } + return num_attachments; +} + +//----------------------------------------------------------------------------- +// canAttachMoreObjects() +//----------------------------------------------------------------------------- +BOOL LLVOAvatar::canAttachMoreObjects() const +{ + return (getNumAttachments() < MAX_AGENT_ATTACHMENTS); +} + +//----------------------------------------------------------------------------- // lazyAttach() //----------------------------------------------------------------------------- void LLVOAvatar::lazyAttach() @@ -5455,10 +5514,15 @@ void LLVOAvatar::resetHUDAttachments() LLViewerJointAttachment* attachment = curiter->second; if (attachment->getIsHUDAttachment()) { - LLViewerObject* obj = attachment->getObject(); - if (obj && obj->mDrawable.notNull()) + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) { - gPipeline.markMoved(obj->mDrawable); + const LLViewerObject* attached_object = (*attachment_iter); + if (attached_object && attached_object->mDrawable.notNull()) + { + gPipeline.markMoved(attached_object->mDrawable); + } } } } @@ -5474,19 +5538,19 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) { attachment_map_t::iterator curiter = iter++; LLViewerJointAttachment* attachment = curiter->second; - // only one object per attachment point for now - if (attachment->getObject() == viewer_object) + + if (attachment->isObjectAttached(viewer_object)) { - LLUUID item_id = attachment->getItemID(); + LLUUID item_id = viewer_object->getItemID(); attachment->removeObject(viewer_object); if (isSelf()) { // the simulator should automatically handle // permission revocation - + stopMotionFromSource(viewer_object->getID()); LLFollowCamMgr::setCameraActive(viewer_object->getID(), FALSE); - + LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); iter != child_list.end(); iter++) @@ -5494,17 +5558,16 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) LLViewerObject* child_objectp = *iter; // the simulator should automatically handle // permissions revocation - + stopMotionFromSource(child_objectp->getID()); LLFollowCamMgr::setCameraActive(child_objectp->getID(), FALSE); } - } lldebugs << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << llendl; if (isSelf()) { // Then make sure the inventory is in sync with the avatar. - + // Update COF contents, don't trigger appearance update. if (gAgent.getAvatarObject() == NULL) { @@ -5514,9 +5577,8 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) { LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Removing attachment link:"); LLAppearanceManager::removeItemLinks(item_id, false); - } - + // BAP - needs to change for label to track link. gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); gInventory.notifyObservers(); @@ -5524,7 +5586,6 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) return TRUE; } } - return FALSE; } @@ -5833,10 +5894,10 @@ void LLVOAvatar::updateMeshTextures() // if user has never specified a texture, assign the default for (U32 i=0; i < getNumTEs(); i++) { - const LLViewerTexture* te_image = getImage(i); + const LLViewerTexture* te_image = getImage(i, 0); if(!te_image || te_image->getID().isNull() || (te_image->getID() == IMG_DEFAULT)) { - setImage(i, LLViewerTextureManager::getFetchedTexture(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), 0); // IMG_DEFAULT_AVATAR = a special texture that's never rendered. } } @@ -5899,7 +5960,7 @@ void LLVOAvatar::updateMeshTextures() } else if (!self_customizing && is_layer_baked[i]) { - LLViewerFetchedTexture* baked_img = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex ), TRUE) ; + LLViewerFetchedTexture* baked_img = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), 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). @@ -5934,7 +5995,7 @@ void LLVOAvatar::updateMeshTextures() if (!is_layer_baked[BAKED_HAIR] || self_customizing) { const LLColor4 color = mTexHairColor ? mTexHairColor->getColor() : LLColor4(1,1,1,1); - LLViewerTexture* hair_img = getImage( TEX_HAIR ); + LLViewerTexture* hair_img = getImage( TEX_HAIR, 0 ); for (U32 i = 0; i < mBakedTextureDatas[BAKED_HAIR].mMeshes.size(); i++) { mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); @@ -5958,7 +6019,10 @@ void LLVOAvatar::updateMeshTextures() { const ETextureIndex texture_index = *local_tex_iter; 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 ); + if (isSelf()) + { + setBakedReady(texture_index, is_baked_ready); + } } } removeMissingBakedTextures(); @@ -5974,6 +6038,13 @@ void LLVOAvatar::setLocalTexture( ETextureIndex type, LLViewerTexture* in_tex, B llassert(0); } +//virtual +void LLVOAvatar::setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index) +{ + // invalid for anyone but self + llassert(0); +} + void LLVOAvatar::addChat(const LLChat& chat) { std::deque<LLChat>::iterator chat_iter; @@ -6079,9 +6150,9 @@ void LLVOAvatar::releaseComponentTextures() { // ! 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 (isTextureDefined(TEX_HAIR_BAKED) && getImage(TEX_HAIR_BAKED,0)->getID() == getImage(TEX_SKIRT_BAKED,0)->getID()) { - if (getImage(TEX_HAIR_BAKED)->getID() != IMG_INVISIBLE) + if (getImage(TEX_HAIR_BAKED,0)->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); @@ -6106,63 +6177,64 @@ void LLVOAvatar::releaseComponentTextures() } } -BOOL LLVOAvatar::teToColorParams( ETextureIndex te, const char* param_name[3] ) +//static +BOOL LLVOAvatar::teToColorParams( ETextureIndex te, U32 *param_name ) { switch( te ) { case TEX_UPPER_SHIRT: - param_name[0] = "shirt_red"; - param_name[1] = "shirt_green"; - param_name[2] = "shirt_blue"; + param_name[0] = 803; //"shirt_red"; + param_name[1] = 804; //"shirt_green"; + param_name[2] = 805; //"shirt_blue"; break; case TEX_LOWER_PANTS: - param_name[0] = "pants_red"; - param_name[1] = "pants_green"; - param_name[2] = "pants_blue"; + param_name[0] = 806; //"pants_red"; + param_name[1] = 807; //"pants_green"; + param_name[2] = 808; //"pants_blue"; break; case TEX_LOWER_SHOES: - param_name[0] = "shoes_red"; - param_name[1] = "shoes_green"; - param_name[2] = "shoes_blue"; + param_name[0] = 812; //"shoes_red"; + param_name[1] = 813; //"shoes_green"; + param_name[2] = 817; //"shoes_blue"; break; case TEX_LOWER_SOCKS: - param_name[0] = "socks_red"; - param_name[1] = "socks_green"; - param_name[2] = "socks_blue"; + param_name[0] = 818; //"socks_red"; + param_name[1] = 819; //"socks_green"; + param_name[2] = 820; //"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"; + param_name[0] = 834; //"jacket_red"; + param_name[1] = 835; //"jacket_green"; + param_name[2] = 836; //"jacket_blue"; break; case TEX_UPPER_GLOVES: - param_name[0] = "gloves_red"; - param_name[1] = "gloves_green"; - param_name[2] = "gloves_blue"; + param_name[0] = 827; //"gloves_red"; + param_name[1] = 829; //"gloves_green"; + param_name[2] = 830; //"gloves_blue"; break; case TEX_UPPER_UNDERSHIRT: - param_name[0] = "undershirt_red"; - param_name[1] = "undershirt_green"; - param_name[2] = "undershirt_blue"; + param_name[0] = 821; //"undershirt_red"; + param_name[1] = 822; //"undershirt_green"; + param_name[2] = 823; //"undershirt_blue"; break; case TEX_LOWER_UNDERPANTS: - param_name[0] = "underpants_red"; - param_name[1] = "underpants_green"; - param_name[2] = "underpants_blue"; + param_name[0] = 824; //"underpants_red"; + param_name[1] = 825; //"underpants_green"; + param_name[2] = 826; //"underpants_blue"; break; case TEX_SKIRT: - param_name[0] = "skirt_red"; - param_name[1] = "skirt_green"; - param_name[2] = "skirt_blue"; + param_name[0] = 921; //"skirt_red"; + param_name[1] = 922; //"skirt_green"; + param_name[2] = 923; //"skirt_blue"; break; default: @@ -6175,7 +6247,7 @@ BOOL LLVOAvatar::teToColorParams( ETextureIndex te, const char* param_name[3] ) void LLVOAvatar::setClothesColor( ETextureIndex te, const LLColor4& new_color, BOOL set_by_user ) { - const char* param_name[3]; + U32 param_name[3]; if( teToColorParams( te, param_name ) ) { setVisualParamWeight( param_name[0], new_color.mV[VX], set_by_user ); @@ -6187,7 +6259,7 @@ void LLVOAvatar::setClothesColor( ETextureIndex te, const LLColor4& new_color, B LLColor4 LLVOAvatar::getClothesColor( ETextureIndex te ) { LLColor4 color; - const char* param_name[3]; + U32 param_name[3]; if( teToColorParams( te, param_name ) ) { color.mV[VX] = getVisualParamWeight( param_name[0] ); @@ -6214,7 +6286,8 @@ void LLVOAvatar::dumpAvatarTEs( const std::string& context ) iter++) { const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second; - const LLViewerTexture* te_image = getImage(iter->first); + // TODO: handle multiple textures for self + const LLViewerTexture* te_image = getImage(iter->first,0); if( !te_image ) { llinfos << " " << texture_dict->mName << ": null ptr" << llendl; @@ -6261,23 +6334,9 @@ BOOL LLVOAvatar::isWearingWearableType(EWearableType type) const tex_iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); tex_iter++) { - const LLVOAvatarDefines::ETextureIndex index = tex_iter->first; 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 (isSelf()) - { - if (isTextureDefined(index)) - { - return TRUE; - } - else - { - return FALSE; - } - } - // If you're checking another avatar's clothing, you don't have component textures. // Thus, you must check to see if the corresponding baked texture is defined. // NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing @@ -6322,7 +6381,7 @@ BOOL LLVOAvatar::hasHUDAttachment() const { attachment_map_t::const_iterator curiter = iter++; LLViewerJointAttachment* attachment = curiter->second; - if (attachment->getIsHUDAttachment() && attachment->getObject()) + if (attachment->getIsHUDAttachment() && attachment->getNumObjects() > 0) { return TRUE; } @@ -6338,20 +6397,24 @@ LLBBox LLVOAvatar::getHUDBBox() const { attachment_map_t::const_iterator curiter = iter++; LLViewerJointAttachment* attachment = curiter->second; - if (attachment->getIsHUDAttachment() && attachment->getObject()) + if (attachment->getIsHUDAttachment()) { - LLViewerObject* hud_object = attachment->getObject(); - - // initialize bounding box to contain identity orientation and center point for attached object - bbox.addPointLocal(hud_object->getPosition()); - // add rotated bounding box for attached object - bbox.addBBoxAgent(hud_object->getBoundingBoxAgent()); - LLViewerObject::const_child_list_t& child_list = hud_object->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++) + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) { - LLViewerObject* child_objectp = *iter; - bbox.addBBoxAgent(child_objectp->getBoundingBoxAgent()); + const LLViewerObject* attached_object = (*attachment_iter); + // initialize bounding box to contain identity orientation and center point for attached object + bbox.addPointLocal(attached_object->getPosition()); + // add rotated bounding box for attached object + bbox.addBBoxAgent(attached_object->getBoundingBoxAgent()); + LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++) + { + const LLViewerObject* child_objectp = *iter; + bbox.addBBoxAgent(child_objectp->getBoundingBoxAgent()); + } } } } @@ -6380,7 +6443,7 @@ void LLVOAvatar::onFirstTEMessageReceived() // (That is, don't do a transition from unbaked to baked.) if (layer_baked) { - LLViewerFetchedTexture* image = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex ), TRUE) ; + LLViewerFetchedTexture* image = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), 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) ) @@ -6635,8 +6698,8 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture if (texture_dict->mIsUsedByBakedTexture) { const ETextureIndex texture_index = iter->first; - const LLViewerTexture *baked_img = self->getImage(texture_index); - if (id == baked_img->getID()) + const LLViewerTexture *baked_img = self->getImage(texture_index, 0); + if (baked_img && id == baked_img->getID()) { const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; self->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1, baked_index); @@ -6645,7 +6708,6 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture { LLImageGL::deleteTextures(1, &(self->mBakedTextureDatas[baked_index].mMaskTexName)); } - self->mBakedTextureDatas[baked_index].mMaskTexName = gl_name; found_texture_id = true; break; @@ -6723,7 +6785,7 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id ) mHeadMesh1.setTexture( head_baked ); */ for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { - LLViewerTexture* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex ); + LLViewerTexture* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex, 0 ); if (id == image_baked->getID()) { mBakedTextureDatas[i].mIsLoaded = true; @@ -6735,14 +6797,14 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id ) } if (mBakedTextureDatas[i].mTexLayerSet) { - mBakedTextureDatas[i].mTexLayerSet->destroyComposite(); + //mBakedTextureDatas[i].mTexLayerSet->destroyComposite(); } 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, getImage(*local_tex_iter), TRUE); + this->setBakedReady(*local_tex_iter, TRUE); } // ! BACKWARDS COMPATIBILITY ! @@ -6798,7 +6860,8 @@ void LLVOAvatar::dumpArchetypeXML( void* ) { if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex)te) == type) { - LLViewerTexture* te_image = avatar->getImage((ETextureIndex)te); + // MULTIPLE_WEARABLES: extend to multiple wearables? + LLViewerTexture* te_image = avatar->getImage((ETextureIndex)te, 0); if( te_image ) { std::string uuid_str; @@ -7585,21 +7648,26 @@ void LLVOAvatar::idleUpdateRenderCost() ++iter) { LLViewerJointAttachment* attachment = iter->second; - LLViewerObject* object = attachment->getObject(); - if (object && !object->isHUDAttachment()) + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) { - LLDrawable* drawable = object->mDrawable; - if (drawable) + const LLViewerObject* attached_object = (*attachment_iter); + if (attached_object && !attached_object->isHUDAttachment()) { - shame += 10; - LLVOVolume* volume = drawable->getVOVolume(); - if (volume) + const LLDrawable* drawable = attached_object->mDrawable; + if (drawable) { - shame += calc_shame(volume, textures); + shame += 10; + const LLVOVolume* volume = drawable->getVOVolume(); + if (volume) + { + shame += calc_shame(volume, textures); + } } } } - } + } shame += textures.size() * 5; @@ -7647,7 +7715,7 @@ const std::string LLVOAvatar::getBakedStatusForPrintout() const } -U32 calc_shame(LLVOVolume* volume, std::set<LLUUID> &textures) +U32 calc_shame(const LLVOVolume* volume, std::set<LLUUID> &textures) { if (!volume) { @@ -7679,20 +7747,20 @@ U32 calc_shame(LLVOVolume* volume, std::set<LLUUID> &textures) const LLVector3& sc = volume->getScale(); scale += (U32) sc.mV[0] + (U32) sc.mV[1] + (U32) sc.mV[2]; - LLDrawable* drawablep = volume->mDrawable; + const LLDrawable* drawablep = volume->mDrawable; if (volume->isSculpted()) { - LLSculptParams *sculpt_params = (LLSculptParams *) volume->getParameterEntry(LLNetworkData::PARAMS_SCULPT); + const LLSculptParams *sculpt_params = (LLSculptParams *) volume->getParameterEntry(LLNetworkData::PARAMS_SCULPT); LLUUID sculpt_id = sculpt_params->getSculptTexture(); textures.insert(sculpt_id); } for (S32 i = 0; i < drawablep->getNumFaces(); ++i) { - LLFace* face = drawablep->getFace(i); + const LLFace* face = drawablep->getFace(i); const LLTextureEntry* te = face->getTextureEntry(); - LLViewerTexture* img = face->getTexture(); + const LLViewerTexture* img = face->getTexture(); textures.insert(img->getID()); @@ -7736,11 +7804,11 @@ U32 calc_shame(LLVOVolume* volume, std::set<LLUUID> &textures) for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); iter != child_list.end(); iter++) { - LLViewerObject* child_objectp = *iter; - LLDrawable* child_drawablep = child_objectp->mDrawable; + const LLViewerObject* child_objectp = *iter; + const LLDrawable* child_drawablep = child_objectp->mDrawable; if (child_drawablep) { - LLVOVolume* child_volumep = child_drawablep->getVOVolume(); + const LLVOVolume* child_volumep = child_drawablep->getVOVolume(); if (child_volumep) { shame += calc_shame(child_volumep, textures); @@ -7774,7 +7842,7 @@ BOOL LLVOAvatar::isTextureDefined(LLVOAvatarDefines::ETextureIndex te, U32 index return FALSE; } - return (getImage(te)->getID() != IMG_DEFAULT_AVATAR && - getImage(te)->getID() != IMG_DEFAULT); + return (getImage(te, index)->getID() != IMG_DEFAULT_AVATAR && + getImage(te, index)->getID() != IMG_DEFAULT); } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index ef5358198d..1180d43438 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -268,12 +268,14 @@ private: public: void updateHeadOffset(); F32 getPelvisToFoot() const { return mPelvisToFoot; } + LLVector3 mHeadOffset; // current head position LLViewerJoint mRoot; protected: static BOOL parseSkeletonFile(const std::string& filename); void buildCharacter(); BOOL loadAvatar(); + BOOL setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 ¤t_volume_num, S32 ¤t_joint_num); BOOL buildSkeleton(const LLVOAvatarSkeletonInfo *info); private: @@ -495,13 +497,15 @@ protected: 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); + // MULTI-WEARABLE: make self-only? + virtual void setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index = 0); //-------------------------------------------------------------------- // Texture accessors //-------------------------------------------------------------------- private: - virtual void setImage(const U8 te, LLViewerTexture *imagep); - virtual LLViewerTexture* getImage(const U8 te) const; + virtual void setImage(const U8 te, LLViewerTexture *imagep, const U32 index); + virtual LLViewerTexture* getImage(const U8 te, const U32 index) const; virtual const LLTextureEntry* getTexEntry(const U8 te_num) const; virtual void setTexEntry(const U8 index, const LLTextureEntry &te); @@ -605,7 +609,7 @@ private: 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]); + static BOOL teToColorParams(LLVOAvatarDefines::ETextureIndex te, U32 *param_name); //-------------------------------------------------------------------- // Global colors @@ -637,14 +641,14 @@ public: **/ public: - BOOL isWearingWearableType(EWearableType type ) const; + virtual BOOL isWearingWearableType(EWearableType type ) const; //-------------------------------------------------------------------- // Attachments //-------------------------------------------------------------------- public: void clampAttachmentPositions(); - virtual LLViewerJointAttachment* attachObject(LLViewerObject *viewer_object); + virtual const LLViewerJointAttachment* attachObject(LLViewerObject *viewer_object); BOOL detachObject(LLViewerObject *viewer_object); static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj); protected: @@ -668,6 +672,9 @@ public: LLBBox getHUDBBox() const; void rebuildHUD(); void resetHUDAttachments(); + BOOL canAttachMoreObjects() const; +protected: + U32 getNumAttachments() const; // O(N), not O(1) /** Wearables ** ** diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 999a39efd1..99e358f409 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -600,7 +600,7 @@ BOOL LLVOAvatarSelf::loadLayersets() morph_iter++) { LLMaskedMorph *morph = *morph_iter; - LLTexLayer * layer = layer_set->findLayerByName(morph->mLayer); + LLTexLayerInterface* layer = layer_set->findLayerByName(morph->mLayer); if (layer) { layer->setHasMorph(TRUE); @@ -642,6 +642,71 @@ LLJoint *LLVOAvatarSelf::getJoint(const std::string &name) return LLVOAvatar::getJoint(name); } +/*virtual*/ BOOL LLVOAvatarSelf::setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL set_by_user ) +{ + if (!which_param) + { + return FALSE; + } + LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(which_param->getID()); + return setParamWeight(param,weight,set_by_user); +} + +/*virtual*/ BOOL LLVOAvatarSelf::setVisualParamWeight(const char* param_name, F32 weight, BOOL set_by_user ) +{ + if (!param_name) + { + return FALSE; + } + LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(param_name); + return setParamWeight(param,weight,set_by_user); +} + +/*virtual*/ BOOL LLVOAvatarSelf::setVisualParamWeight(S32 index, F32 weight, BOOL set_by_user ) +{ + LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(index); + return setParamWeight(param,weight,set_by_user); +} + +BOOL LLVOAvatarSelf::setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL set_by_user ) +{ + if (!param) + { + return FALSE; + } + + if (param->getCrossWearable()) + { + EWearableType type = (EWearableType)param->getWearableType(); + U32 size = gAgentWearables.getWearableCount(type); + for (U32 count = 0; count < size; ++count) + { + LLWearable *wearable = gAgentWearables.getWearable(type,count); + if (wearable) + { + wearable->setVisualParamWeight(param->getID(), weight, set_by_user); + } + } + } + + return LLCharacter::setVisualParamWeight(param,weight,set_by_user); +} + +/*virtual*/ +void LLVOAvatarSelf::updateVisualParams() +{ + for (U32 type = 0; type < WT_COUNT; type++) + { + LLWearable *wearable = gAgentWearables.getTopWearable((EWearableType)type); + if (wearable) + { + wearable->writeToAvatar(FALSE, FALSE); + } + } + + LLVOAvatar::updateVisualParams(); +} + // virtual void LLVOAvatarSelf::requestStopMotion(LLMotion* motion) { @@ -872,6 +937,11 @@ void LLVOAvatarSelf::updateAttachmentVisibility(U32 camera_mode) } } +/*virtual*/ BOOL LLVOAvatarSelf::isWearingWearableType(EWearableType type ) const +{ + return gAgentWearables.getWearableCount(type) > 0; +} + //----------------------------------------------------------------------------- // updatedWearable( EWearableType type ) // forces an update to any baked textures relevant to type. @@ -917,7 +987,7 @@ BOOL LLVOAvatarSelf::isWearingAttachment( const LLUUID& inv_item_id , BOOL inclu { attachment_map_t::const_iterator curiter = iter++; const LLViewerJointAttachment* attachment = curiter->second; - if( attachment->getItemID() == inv_item_id ) + if (attachment->getAttachedObject(inv_item_id)) { return TRUE; } @@ -938,7 +1008,7 @@ BOOL LLVOAvatarSelf::isWearingAttachment( const LLUUID& inv_item_id , BOOL inclu { attachment_map_t::const_iterator curiter = iter++; const LLViewerJointAttachment* attachment = curiter->second; - if( attachment->getItemID() == item_id ) + if (attachment->getAttachedObject(item_id)) { return TRUE; } @@ -952,16 +1022,16 @@ BOOL LLVOAvatarSelf::isWearingAttachment( const LLUUID& inv_item_id , BOOL inclu //----------------------------------------------------------------------------- // getWornAttachment() //----------------------------------------------------------------------------- -LLViewerObject* LLVOAvatarSelf::getWornAttachment( const LLUUID& inv_item_id ) const +LLViewerObject* LLVOAvatarSelf::getWornAttachment( const LLUUID& inv_item_id ) { - for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + for (attachment_map_t::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 ) + attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + if (LLViewerObject *attached_object = attachment->getAttachedObject(inv_item_id)) { - return attachment->getObject(); + return attached_object; } } return NULL; @@ -974,7 +1044,7 @@ const std::string LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id { attachment_map_t::const_iterator curiter = iter++; const LLViewerJointAttachment* attachment = curiter->second; - if( attachment->getItemID() == inv_item_id ) + if (attachment->getAttachedObject(inv_item_id)) { return attachment->getName(); } @@ -984,9 +1054,9 @@ const std::string LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id } //virtual -LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *viewer_object) +const LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *viewer_object) { - LLViewerJointAttachment *attachment = LLVOAvatar::attachObject(viewer_object); + const LLViewerJointAttachment *attachment = LLVOAvatar::attachObject(viewer_object); if (!attachment) { return 0; @@ -995,14 +1065,20 @@ LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *viewer_obj updateAttachmentVisibility(gAgent.getCameraMode()); // Then make sure the inventory is in sync with the avatar. - LLViewerInventoryItem *item = gInventory.getItem(attachment->getItemID()); - if (item) - { - LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Adding attachment link:"); - LLAppearanceManager::wearItem(item,false); // Add COF link for item. + // Should just be the last object added + if (attachment->isObjectAttached(viewer_object)) + { + const LLUUID& attachment_id = viewer_object->getItemID(); + LLViewerInventoryItem *item = gInventory.getItem(attachment_id); + if (item) + { + LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Adding attachment link:"); + LLAppearanceManager::wearItem(item,false); // Add COF link for item. + gInventory.addChangedMask(LLInventoryObserver::LABEL, attachment_id); + } } - gInventory.addChangedMask(LLInventoryObserver::LABEL, attachment->getItemID()); + gInventory.notifyObservers(); return attachment; @@ -1116,6 +1192,25 @@ BOOL LLVOAvatarSelf::getLocalTextureGL(ETextureIndex type, LLViewerTexture** tex return TRUE; } +LLViewerFetchedTexture* LLVOAvatarSelf::getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, U32 index) const +{ + if (!isIndexLocalTexture(type)) + { + return NULL; + } + + const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index); + if (!local_tex_obj) + { + return NULL; + } + if (local_tex_obj->getID() == IMG_DEFAULT_AVATAR) + { + return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR); + } + return local_tex_obj->getImage(); +} + const LLUUID& LLVOAvatarSelf::getLocalTextureID(ETextureIndex type, U32 index) const { if (!isIndexLocalTexture(type)) return IMG_DEFAULT_AVATAR; @@ -1126,7 +1221,8 @@ const LLUUID& LLVOAvatarSelf::getLocalTextureID(ETextureIndex type, U32 index) c return local_tex_obj->getImage()->getID(); } return IMG_DEFAULT_AVATAR; -} +} + //----------------------------------------------------------------------------- // isLocalTextureDataAvailable() @@ -1151,7 +1247,12 @@ BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLTexLayerSet* layerset) local_tex_iter++) { const ETextureIndex tex_index = *local_tex_iter; - ret &= (getLocalDiscardLevel(tex_index) >= 0); + const EWearableType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index); + const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); + for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) + { + ret &= (getLocalDiscardLevel(tex_index, wearable_index) >= 0); + } } return ret; } @@ -1177,9 +1278,15 @@ BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLTexLayerSet* layerset) cons local_tex_iter != baked_dict->mLocalTextures.end(); local_tex_iter++) { - if (getLocalDiscardLevel(*local_tex_iter) != 0) + const ETextureIndex tex_index = *local_tex_iter; + const EWearableType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index); + const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); + for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) { - return FALSE; + if (getLocalDiscardLevel(*local_tex_iter, wearable_index) != 0) + { + return FALSE; + } } } return TRUE; @@ -1192,17 +1299,33 @@ BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLTexLayerSet* layerset) cons BOOL LLVOAvatarSelf::isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index) const { LLUUID id; + BOOL isDefined = TRUE; if (isIndexLocalTexture(type)) { - id = getLocalTextureID(type, index); + const EWearableType wearable_type = LLVOAvatarDictionary::getTEWearableType(type); + const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); + if (index >= wearable_count) + { + // invalid index passed in. check all textures of a given type + for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) + { + id = getLocalTextureID(type, wearable_index); + isDefined &= (id != IMG_DEFAULT_AVATAR && id != IMG_DEFAULT); + } + } + else + { + id = getLocalTextureID(type, index); + isDefined &= (id != IMG_DEFAULT_AVATAR && id != IMG_DEFAULT); + } } else { id = getTEImage(type)->getID(); + isDefined &= (id != IMG_DEFAULT_AVATAR && id != IMG_DEFAULT); } - - return (id != IMG_DEFAULT_AVATAR && - id != IMG_DEFAULT); + + return isDefined; } //----------------------------------------------------------------------------- @@ -1213,7 +1336,8 @@ void LLVOAvatarSelf::requestLayerSetUploads() { for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { - BOOL layer_baked = isTextureDefined(mBakedTextureDatas[i].mTextureIndex); + ETextureIndex tex_index = mBakedTextureDatas[i].mTextureIndex; + BOOL layer_baked = isTextureDefined(tex_index, gAgentWearables.getWearableCount(tex_index)); if (!layer_baked && mBakedTextureDatas[i].mTexLayerSet) { mBakedTextureDatas[i].mTexLayerSet->requestUpload(); @@ -1288,7 +1412,8 @@ void LLVOAvatarSelf::setupComposites() { for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { - BOOL layer_baked = isTextureDefined(mBakedTextureDatas[i].mTextureIndex); + ETextureIndex tex_index = mBakedTextureDatas[i].mTextureIndex; + BOOL layer_baked = isTextureDefined(tex_index, gAgentWearables.getWearableCount(tex_index)); if (mBakedTextureDatas[i].mTexLayerSet) { mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled(!layer_baked); @@ -1309,15 +1434,15 @@ void LLVOAvatarSelf::updateComposites() } // virtual -S32 LLVOAvatarSelf::getLocalDiscardLevel(ETextureIndex type, U32 index) const +S32 LLVOAvatarSelf::getLocalDiscardLevel(ETextureIndex type, U32 wearable_index) const { if (!isIndexLocalTexture(type)) return FALSE; - const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index); + const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, wearable_index); if (local_tex_obj) { if (type >= 0 - && getLocalTextureID(type,index) != IMG_DEFAULT_AVATAR + && local_tex_obj->getID() != IMG_DEFAULT_AVATAR && !local_tex_obj->getImage()->isMissingAsset()) { return local_tex_obj->getImage()->getDiscardLevel(); @@ -1381,7 +1506,7 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te return; } EWearableType wearable_type = LLVOAvatarDictionary::getInstance()->getTEWearableType(type); - if (!gAgentWearables.getWearable(wearable_type,0)) + if (!gAgentWearables.getWearable(wearable_type,index)) { // no wearable is loaded, cannot set the texture. return; @@ -1393,6 +1518,13 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te llerrs << "Unable to create LocalTextureObject for wearable type & index: (" << (U32) wearable_type << ", " << index << ")" << llendl; return; } + + LLTexLayerSet *layer_set = getLayerSet(type); + if (layer_set) + { + layer_set->cloneTemplates(local_tex_obj, type, gAgentWearables.getWearable(wearable_type,index)); + } + } if (!baked_version_ready) { @@ -1425,10 +1557,22 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te tex->setMinDiscardLevel(desired_discard); } } - local_tex_obj->setBakedReady( baked_version_ready ); local_tex_obj->setImage(tex); + local_tex_obj->setID(tex->getID()); + setBakedReady(type,baked_version_ready,index); +} +//virtual +void LLVOAvatarSelf::setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index) +{ + if (!isIndexLocalTexture(type)) return; + LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type,index); + if (local_tex_obj) + { + local_tex_obj->setBakedReady( baked_version_exists ); + } } + // virtual void LLVOAvatarSelf::dumpLocalTextures() const { @@ -1450,7 +1594,8 @@ void LLVOAvatarSelf::dumpLocalTextures() const const std::string &name = texture_dict->mName; const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(iter->first, 0); - if (isTextureDefined(baked_equiv)) + // index is baked texture - index is not relevant. putting in 0 as placeholder + if (isTextureDefined(baked_equiv, 0)) { #if LL_RELEASE_FOR_DOWNLOAD // End users don't get to trivially see avatar texture IDs, makes textures @@ -1510,6 +1655,31 @@ void LLVOAvatarSelf::onLocalTextureLoaded(BOOL success, LLViewerFetchedTexture * } } +/*virtual*/ void LLVOAvatarSelf::setImage(const U8 te, LLViewerTexture *imagep, const U32 index) +{ + if (isIndexLocalTexture((ETextureIndex)te)) + { + setLocalTexture((ETextureIndex)te, imagep, FALSE ,index); + } + else + { + setTEImage(te,imagep); + } +} + +/*virtual*/ LLViewerTexture* LLVOAvatarSelf::getImage(const U8 te, const U32 index) const +{ + if (isIndexLocalTexture((ETextureIndex)te)) + { + return getLocalTextureGL((ETextureIndex)te,index); + } + else + { + return getTEImage(te); + } +} + + // static void LLVOAvatarSelf::dumpTotalLocalTextureByteCount() { @@ -1528,7 +1698,7 @@ BOOL LLVOAvatarSelf::updateIsFullyLoaded() loading = TRUE; } - if (!isTextureDefined(TEX_HAIR)) + if (!isTextureDefined(TEX_HAIR, 0)) { loading = TRUE; } @@ -1536,13 +1706,13 @@ BOOL LLVOAvatarSelf::updateIsFullyLoaded() if (!mPreviousFullyLoaded) { if (!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_LOWER].mTexLayerSet) && - (!isTextureDefined(TEX_LOWER_BAKED))) + (!isTextureDefined(TEX_LOWER_BAKED, 0))) { loading = TRUE; } if (!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_UPPER].mTexLayerSet) && - (!isTextureDefined(TEX_UPPER_BAKED))) + (!isTextureDefined(TEX_UPPER_BAKED, 0))) { loading = TRUE; } @@ -1553,11 +1723,11 @@ BOOL LLVOAvatarSelf::updateIsFullyLoaded() continue; BakedTextureData& texture_data = mBakedTextureDatas[i]; - if (!isTextureDefined(texture_data.mTextureIndex)) + if (!isTextureDefined(texture_data.mTextureIndex, 0)) continue; // Check for the case that texture is defined but not sufficiently loaded to display anything. - LLViewerTexture* baked_img = getImage( texture_data.mTextureIndex ); + LLViewerTexture* baked_img = getImage( texture_data.mTextureIndex, 0 ); if (!baked_img || !baked_img->hasGLTexture()) { loading = TRUE; @@ -1581,9 +1751,9 @@ const LLUUID& LLVOAvatarSelf::grabLocalTexture(ETextureIndex type, U32 index) co BOOL LLVOAvatarSelf::canGrabLocalTexture(ETextureIndex type, U32 index) const { // Check if the texture hasn't been baked yet. - if (!isTextureDefined(type)) + if (!isTextureDefined(type, index)) { - lldebugs << "getTEImage( " << (U32) type << " )->getID() == IMG_DEFAULT_AVATAR" << llendl; + lldebugs << "getTEImage( " << (U32) type << ", " << index << " )->getID() == IMG_DEFAULT_AVATAR" << llendl; return FALSE; } @@ -1607,6 +1777,7 @@ BOOL LLVOAvatarSelf::canGrabLocalTexture(ETextureIndex type, U32 index) const { const ETextureIndex t_index = (*iter); lldebugs << "Checking index " << (U32) t_index << llendl; + // MULTI-WEARABLE: old method. replace. const LLUUID& texture_id = getTEImage( t_index )->getID(); if (texture_id != IMG_DEFAULT_AVATAR) { diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 17744cce1b..0b76d3e960 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -85,6 +85,16 @@ public: /*virtual*/ void requestStopMotion(LLMotion* motion); /*virtual*/ LLJoint* getJoint(const std::string &name); + /*virtual*/ BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL set_by_user = FALSE ); + /*virtual*/ BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL set_by_user = FALSE ); + /*virtual*/ BOOL setVisualParamWeight(S32 index, F32 weight, BOOL set_by_user = FALSE ); + /*virtual*/ void updateVisualParams(); + +private: + // helper function. Passed in param is assumed to be in avatar's parameter list. + BOOL setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL set_by_user = FALSE ); + + /** Initialization ** ** *******************************************************************************/ @@ -160,31 +170,38 @@ public: //-------------------------------------------------------------------- public: /*virtual*/ bool hasPendingBakedUploads() const; - S32 getLocalDiscardLevel(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const; + S32 getLocalDiscardLevel(LLVOAvatarDefines::ETextureIndex type, U32 index) 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; + // If you want to check all textures of a given type, pass gAgentWearables.getWearableCount() for index + /*virtual*/ BOOL isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index) 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; + BOOL getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture** image_gl_pp, U32 index) const; + LLViewerFetchedTexture* getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, U32 index) const; + const LLUUID& getLocalTextureID(LLVOAvatarDefines::ETextureIndex type, U32 index) const; + void setLocalTextureTE(U8 te, LLViewerTexture* image, BOOL set_by_user, U32 index); + const LLUUID& grabLocalTexture(LLVOAvatarDefines::ETextureIndex type, U32 index) const; + BOOL canGrabLocalTexture(LLVOAvatarDefines::ETextureIndex type, U32 index) const; protected: - /*virtual*/ void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index = 0); + /*virtual*/ void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index); + /*virtual*/ void setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index); 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; + /*virtual*/ void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex i, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index); + LLLocalTextureObject* getLocalTextureObject(LLVOAvatarDefines::ETextureIndex i, U32 index) const; private: static void onLocalTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); + /*virtual*/ void setImage(const U8 te, LLViewerTexture *imagep, const U32 index); + /*virtual*/ LLViewerTexture* getImage(const U8 te, const U32 index) const; + + //-------------------------------------------------------------------- // Baked textures //-------------------------------------------------------------------- @@ -203,7 +220,7 @@ protected: public: void requestLayerSetUploads(); void requestLayerSetUpdate(LLVOAvatarDefines::ETextureIndex i); -protected: +public: LLTexLayerSet* getLayerSet(LLVOAvatarDefines::ETextureIndex index) const; //-------------------------------------------------------------------- @@ -250,6 +267,7 @@ protected: **/ public: + /*virtual*/ BOOL isWearingWearableType(EWearableType type ) const; void wearableUpdated(EWearableType type); //-------------------------------------------------------------------- @@ -258,9 +276,9 @@ public: 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; + LLViewerObject* getWornAttachment(const LLUUID& inv_item_id ); const std::string getAttachedPointName(const LLUUID& inv_item_id) const; - /*virtual*/ LLViewerJointAttachment *attachObject(LLViewerObject *viewer_object); + /*virtual*/ const LLViewerJointAttachment *attachObject(LLViewerObject *viewer_object); void getAllAttachmentsArray(LLDynamicArray<S32>& attachments); //-------------------------------------------------------------------- diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 1704f63376..98b3ba8f45 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1834,6 +1834,53 @@ bool LLVOVolume::hasNavigatePermission(const LLMediaEntry* media_entry) } +void LLVOVolume::mediaNavigated(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, std::string new_location) +{ + bool block_navigation = false; + // FIXME: if/when we allow the same media impl to be used by multiple faces, the logic here will need to be fixed + // to deal with multiple face indices. + int face_index = getFaceIndexWithMediaImpl(impl, -1); + + // Find the media entry for this navigate + LLMediaEntry* mep = NULL; + LLTextureEntry *te = getTE(face_index); + if(te) + { + mep = te->getMediaData(); + } + + if(mep) + { + if(!mep->checkCandidateUrl(new_location)) + { + block_navigation = true; + } + if (!block_navigation && !hasNavigatePermission(mep)) + { + block_navigation = true; + } + } + else + { + llwarns << "Couldn't find media entry!" << llendl; + } + + if(block_navigation) + { + llinfos << "blocking navigate to URI " << new_location << llendl; + + // "bounce back" to the current URL from the media entry + mediaNavigateBounceBack(face_index); + } + else + { + + llinfos << "broadcasting navigate with URI " << new_location << llendl; + + sObjectMediaNavigateClient->navigate(new LLMediaDataClientObjectImpl(this), face_index, new_location); + } +} + void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event) { switch(event) @@ -1845,52 +1892,8 @@ void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, { case LLViewerMediaImpl::MEDIANAVSTATE_FIRST_LOCATION_CHANGED: { - // This is the first location changed event after the start of a non-server-directed nav. It may need to be broadcast. - - bool block_navigation = false; - // FIXME: if/when we allow the same media impl to be used by multiple faces, the logic here will need to be fixed - // to deal with multiple face indices. - int face_index = getFaceIndexWithMediaImpl(impl, -1); - std::string new_location = plugin->getLocation(); - - // Find the media entry for this navigate - LLMediaEntry* mep = NULL; - LLTextureEntry *te = getTE(face_index); - if(te) - { - mep = te->getMediaData(); - } - - if(mep) - { - if(!mep->checkCandidateUrl(new_location)) - { - block_navigation = true; - } - if (!block_navigation && !hasNavigatePermission(mep)) - { - block_navigation = true; - } - } - else - { - llwarns << "Couldn't find media entry!" << llendl; - } - - if(block_navigation) - { - llinfos << "blocking navigate to URI " << new_location << llendl; - - // "bounce back" to the current URL from the media entry - mediaNavigateBounceBack(face_index); - } - else - { - - llinfos << "broadcasting navigate with URI " << new_location << llendl; - - sObjectMediaNavigateClient->navigate(new LLMediaDataClientObjectImpl(this), face_index, new_location); - } + // This is the first location changed event after the start of a non-server-directed nav. It may need to be broadcast or bounced back. + mediaNavigated(impl, plugin, plugin->getLocation()); } break; @@ -1907,6 +1910,29 @@ void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, } break; + case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_COMPLETE: + { + switch(impl->getNavState()) + { + case LLViewerMediaImpl::MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED: + { + // This is the first location changed event after the start of a non-server-directed nav. It may need to be broadcast or bounced back. + mediaNavigated(impl, plugin, plugin->getNavigateURI()); + } + break; + + case LLViewerMediaImpl::MEDIANAVSTATE_SERVER_COMPLETE_BEFORE_LOCATION_CHANGED: + // This is the the navigate complete event from a server-directed nav. Don't broadcast it. + llinfos << " NOT broadcasting navigate (server-directed)" << llendl; + break; + + default: + // For all other states, the navigate should have been handled by LOCATION_CHANGED events already. + break; + } + } + break; + default: break; } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 90dfa2204b..d8ae9a5453 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -245,6 +245,7 @@ public: // Returns whether or not this object has permission to navigate the given media entry bool hasNavigatePermission(const LLMediaEntry* media_entry); + void mediaNavigated(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, std::string new_location); void mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event); // Sync the given media data with the impl and the given te diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index 0d3dd10a01..09e8c522b0 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -44,6 +44,9 @@ #include "llwearable.h" #include "lldictionary.h" #include "lltrans.h" +#include "lltexlayer.h" +#include "llvisualparam.h" +#include "lltexglobalcolor.h" using namespace LLVOAvatarDefines; @@ -129,17 +132,18 @@ BOOL LLWearable::exportFile(LLFILE* file) const } // parameters - S32 num_parameters = mVisualParamMap.size(); + S32 num_parameters = mVisualParamIndexMap.size(); if( fprintf( file, "parameters %d\n", num_parameters ) < 0 ) { return FALSE; } - for (param_map_t::const_iterator iter = mVisualParamMap.begin(); - iter != mVisualParamMap.end(); ++iter) + for (VisualParamIndexMap_t::const_iterator iter = mVisualParamIndexMap.begin(); + iter != mVisualParamIndexMap.end(); ++iter) { S32 param_id = iter->first; - F32 param_weight = iter->second; + LLVisualParam* param = iter->second; + F32 param_weight = param->getWeight(); if( fprintf( file, "%d %s\n", param_id, terse_F32_to_string( param_weight ).c_str() ) < 0 ) { return FALSE; @@ -156,7 +160,7 @@ BOOL LLWearable::exportFile(LLFILE* file) const for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter) { S32 te = iter->first; - const LLUUID& image_id = iter->second.getID(); + const LLUUID& image_id = iter->second->getID(); if( fprintf( file, "%d %s\n", te, image_id.asString().c_str()) < 0 ) { return FALSE; @@ -165,6 +169,43 @@ BOOL LLWearable::exportFile(LLFILE* file) const return TRUE; } + +void LLWearable::createVisualParams() +{ + LLVOAvatar* avatar = gAgent.getAvatarObject(); + for( LLViewerVisualParam* param = (LLViewerVisualParam*) avatar->getFirstVisualParam(); + param; + param = (LLViewerVisualParam*) avatar->getNextVisualParam() ) + { + if( (param->getWearableType() == mType) ) + { + if( mVisualParamIndexMap[param->getID()] ) + { + delete mVisualParamIndexMap[param->getID()]; + } + mVisualParamIndexMap[param->getID()] = param->cloneParam(this); + } + } + + // resync driver parameters to point to the newly cloned driven parameters + for( VisualParamIndexMap_t::iterator param_iter = mVisualParamIndexMap.begin(); param_iter != mVisualParamIndexMap.end(); param_iter++ ) + { + LLVisualParam* param = param_iter->second; + LLVisualParam*(LLWearable::*wearable_function)(S32)const = &LLWearable::getVisualParam; + // need this line to disambiguate between versions of LLCharacter::getVisualParam() + LLVisualParam*(LLVOAvatarSelf::*avatar_function)(S32)const = &LLVOAvatarSelf::getVisualParam; + param->resetDrivenParams(); + if(!param->linkDrivenParams(boost::bind(wearable_function,(LLWearable*)this, _1), false)) + { + if( !param->linkDrivenParams(boost::bind(avatar_function,(LLVOAvatarSelf*)avatar,_1 ), true)) + { + llwarns << "could not link driven params for wearable " << getName() << " id: " << param->getID() << llendl; + continue; + } + } + } +} + BOOL LLWearable::importFile( LLFILE* file ) { // *NOTE: changing the type or size of this buffer will require @@ -287,7 +328,7 @@ BOOL LLWearable::importFile( LLFILE* file ) } if( 0 <= type && type < WT_COUNT ) { - mType = (EWearableType)type; + setType((EWearableType)type); } else { @@ -296,7 +337,6 @@ BOOL LLWearable::importFile( LLFILE* file ) return FALSE; } - // parameters header S32 num_parameters = 0; fields_read = fscanf( file, "parameters %d\n", &num_parameters ); @@ -306,6 +346,11 @@ BOOL LLWearable::importFile( LLFILE* file ) return FALSE; } + if( num_parameters != mVisualParamIndexMap.size() ) + { + llwarns << "Wearable parameter mismatch. Reading in " << num_parameters << " from file, but created " << mVisualParamIndexMap.size() << " from avatar parameters. " << llendl; + } + // parameters S32 i; for( i = 0; i < num_parameters; i++ ) @@ -318,7 +363,7 @@ BOOL LLWearable::importFile( LLFILE* file ) llwarns << "Bad Wearable asset: bad parameter, #" << i << llendl; return FALSE; } - mVisualParamMap[param_id] = param_weight; + mSavedVisualParamMap[param_id] = param_weight; } // textures header @@ -349,11 +394,25 @@ BOOL LLWearable::importFile( LLFILE* file ) llwarns << "Bad Wearable asset: bad texture uuid: " << text_buffer << llendl; return FALSE; } - - //TODO: check old values - mTEMap[te] = LLLocalTextureObject(NULL, NULL, NULL, LLUUID(text_buffer)); + LLUUID id = LLUUID(text_buffer); + LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture( id ); + if( mTEMap.find(te) != mTEMap.end() ) + { + delete mTEMap[te]; + } + if( mSavedTEMap.find(te) != mSavedTEMap.end() ) + { + delete mSavedTEMap[te]; + } + + mTEMap[te] = new LLLocalTextureObject(image, LLUUID(text_buffer)); + mSavedTEMap[te] = new LLLocalTextureObject(image, LLUUID(text_buffer)); + createLayers(te); } + // copy all saved param values to working params + revertValues(); + return TRUE; } @@ -389,13 +448,13 @@ BOOL LLWearable::isOldVersion() const if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) { param_count++; - if( !is_in_map(mVisualParamMap, param->getID() ) ) + if( !is_in_map(mVisualParamIndexMap, param->getID() ) ) { return TRUE; } } } - if( param_count != mVisualParamMap.size() ) + if( param_count != mVisualParamIndexMap.size() ) { return TRUE; } @@ -442,13 +501,17 @@ BOOL LLWearable::isDirty() const param; param = (LLViewerVisualParam*) avatar->getNextVisualParam() ) { - if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) + if( (param->getWearableType() == mType) + && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) + && !param->getCrossWearable()) { - F32 weight = get_if_there(mVisualParamMap, param->getID(), param->getDefaultWeight()); - weight = llclamp( weight, param->getMinWeight(), param->getMaxWeight() ); + F32 current_weight = getVisualParamWeight(param->getID()); + current_weight = llclamp( current_weight, param->getMinWeight(), param->getMaxWeight() ); + F32 saved_weight = get_if_there(mSavedVisualParamMap, param->getID(), param->getDefaultWeight()); + saved_weight = llclamp( saved_weight, param->getMinWeight(), param->getMaxWeight() ); - U8 a = F32_to_U8( param->getWeight(), param->getMinWeight(), param->getMaxWeight() ); - U8 b = F32_to_U8( weight, param->getMinWeight(), param->getMaxWeight() ); + U8 a = F32_to_U8( saved_weight, param->getMinWeight(), param->getMaxWeight() ); + U8 b = F32_to_U8( current_weight, param->getMinWeight(), param->getMaxWeight() ); if( a != b ) { return TRUE; @@ -460,21 +523,24 @@ BOOL LLWearable::isDirty() const { if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) { - LLViewerTexture* avatar_image = avatar->getTEImage( te ); - if( !avatar_image ) - { - llassert( 0 ); - continue; - } - - te_map_t::const_iterator iter = mTEMap.find(te); - if(iter != mTEMap.end()) + te_map_t::const_iterator current_iter = mTEMap.find(te); + if(current_iter != mTEMap.end()) { - const LLUUID& image_id = iter->second.getID(); - if (avatar_image->getID() != image_id) - { - return TRUE; - } + const LLUUID& current_image_id = current_iter->second->getID(); + te_map_t::const_iterator saved_iter = mSavedTEMap.find(te); + if(saved_iter != mSavedTEMap.end()) + { + const LLUUID& saved_image_id = saved_iter->second->getID(); + if (saved_image_id != current_image_id) + { + return TRUE; + } + } + else + { + // image found in current image list but not saved image list + return FALSE; + } } } } @@ -500,35 +566,47 @@ void LLWearable::setParamsToDefaults() return; } - mVisualParamMap.clear(); for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) { if( (((LLViewerVisualParam*)param)->getWearableType() == mType ) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) { - mVisualParamMap[param->getID()] = param->getDefaultWeight(); + setVisualParamWeight(param->getID(),param->getDefaultWeight(), FALSE); } } } void LLWearable::setTexturesToDefaults() { - mTEMap.clear(); for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) { if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) { - mTEMap[te] = LLLocalTextureObject(NULL, NULL, NULL, LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te)); + LLUUID id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te); + LLViewerFetchedTexture * image = LLViewerTextureManager::getFetchedTexture( id ); + if( mTEMap.find(te) == mTEMap.end() ) + { + mTEMap[te] = new LLLocalTextureObject(image, id); + createLayers(te); + } + else + { + // Local Texture Object already created, just set image and UUID + LLLocalTextureObject *lto = mTEMap[te]; + lto->setID(id); + lto->setImage(image); + } } } } // Updates the user's avatar's appearance -void LLWearable::writeToAvatar( BOOL set_by_user ) +void LLWearable::writeToAvatar( BOOL set_by_user, BOOL update_customize_floater ) { LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); llassert( avatar ); if( !avatar ) { + llerrs << "could not get avatar object to write to for wearable " << this->getName() << llendl; return; } @@ -537,10 +615,11 @@ void LLWearable::writeToAvatar( BOOL set_by_user ) // Pull params for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) { - if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) + if( (((LLViewerVisualParam*)param)->getWearableType() == mType) ) { S32 param_id = param->getID(); - F32 weight = get_if_there(mVisualParamMap, param_id, param->getDefaultWeight()); + F32 weight = getVisualParamWeight(param_id); + // only animate with user-originated changes if (set_by_user) { @@ -568,20 +647,20 @@ void LLWearable::writeToAvatar( BOOL set_by_user ) LLUUID image_id; if(iter != mTEMap.end()) { - image_id = iter->second.getID(); + 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); + // MULTI-WEARABLE: replace hard-coded 0 + avatar->setLocalTextureTE(te, image, set_by_user, 0); } } - avatar->updateVisualParams(); - if( gFloaterCustomize ) + if( gFloaterCustomize && update_customize_floater ) { LLViewerInventoryItem* item; // MULTI_WEARABLE: @@ -615,6 +694,7 @@ void LLWearable::writeToAvatar( BOOL set_by_user ) // } } + // Updates the user's avatar's appearance, replacing this wearables' parameters and textures with default values. // static void LLWearable::removeFromAvatar( EWearableType type, BOOL set_by_user ) @@ -645,16 +725,6 @@ void LLWearable::removeFromAvatar( EWearableType type, BOOL set_by_user ) } } - // Pull textures - LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( IMG_DEFAULT_AVATAR ); - for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) - { - if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == type) - { - avatar->setLocalTextureTE(te, image, set_by_user); - } - } - if( gFloaterCustomize ) { gFloaterCustomize->setWearable(type, NULL, PERM_ALL, TRUE); @@ -669,53 +739,11 @@ void LLWearable::removeFromAvatar( EWearableType type, BOOL set_by_user ) // } } - - -// Updates asset from the user's avatar -void LLWearable::readFromAvatar() -{ - LLVOAvatar* avatar = gAgent.getAvatarObject(); - llassert( avatar ); - if( !avatar ) - { - return; - } - - mDefinitionVersion = LLWearable::sCurrentDefinitionVersion; - - mVisualParamMap.clear(); - for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) - { - if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) - { - mVisualParamMap[param->getID()] = param->getWeight(); - } - } - - mTEMap.clear(); - for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) - { - if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) - { - LLViewerTexture* image = avatar->getTEImage( te ); - if( image ) - { - mTEMap[te] = LLLocalTextureObject(NULL, NULL, NULL, image->getID()); - } - } - } - - //if( gFloaterCustomize ) - //{ - // mDescription = gFloaterCustomize->getWearableDescription( mType ); - //} -} - // Does not copy mAssetID. // Definition version is current: removes obsolete enties and creates default values for new ones. void LLWearable::copyDataFrom(const LLWearable* src) { - LLVOAvatar* avatar = gAgent.getAvatarObject(); + LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); llassert( avatar ); if( !avatar ) { @@ -730,37 +758,55 @@ void LLWearable::copyDataFrom(const LLWearable* src) mSaleInfo = src->mSaleInfo; mType = src->mType; + mSavedVisualParamMap.clear(); // Deep copy of mVisualParamMap (copies only those params that are current, filling in defaults where needed) for( LLViewerVisualParam* param = (LLViewerVisualParam*) avatar->getFirstVisualParam(); param; param = (LLViewerVisualParam*) avatar->getNextVisualParam() ) { - if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) + if( (param->getWearableType() == mType) ) { S32 id = param->getID(); - F32 weight = get_if_there(src->mVisualParamMap, id, param->getDefaultWeight() ); - mVisualParamMap[id] = weight; + F32 weight = src->getVisualParamWeight(id); + mSavedVisualParamMap[id] = weight; + + // Clones a visual param from src and adds it to this wearable. Value of param is taken from current value of source param, not saved. + addVisualParam(param->cloneParam(this)); } } + destroyTextures(); // 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 (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) { - te_map_t::const_iterator iter = mTEMap.find(te); + te_map_t::const_iterator iter = src->mTEMap.find(te); LLUUID image_id; - if(iter != mTEMap.end()) + LLViewerFetchedTexture *image = NULL; + if(iter != src->mTEMap.end()) { - image_id = iter->second.getID(); + image = src->getConstLocalTextureObject(te)->getImage(); + image_id = src->getConstLocalTextureObject(te)->getID(); + mTEMap[te] = new LLLocalTextureObject(image, image_id); + mSavedTEMap[te] = new LLLocalTextureObject(image, image_id); + mTEMap[te]->setBakedReady(src->getConstLocalTextureObject(te)->getBakedReady()); + mTEMap[te]->setDiscard(src->getConstLocalTextureObject(te)->getDiscard()); } else { image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te); + image = LLViewerTextureManager::getFetchedTexture( image_id ); + mTEMap[te] = new LLLocalTextureObject(image, image_id); + mSavedTEMap[te] = new LLLocalTextureObject(image, image_id); } - mTEMap[te] = LLLocalTextureObject(NULL, NULL, NULL, image_id); + createLayers(te); } } + + // Probably reduntant, but ensure that the newly created wearable is not dirty by setting current value of params in new wearable + // to be the same as the saved values (which were loaded from src at param->cloneParam(this)) + revertValues(); } void LLWearable::setItemID(const LLUUID& item_id) @@ -773,29 +819,263 @@ const LLUUID& LLWearable::getItemID() const return mItemID; } -LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) const +void LLWearable::setType(EWearableType type) +{ + mType = type; + createVisualParams(); +} + +LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) +{ + te_map_t::iterator iter = mTEMap.find(index); + if( iter != mTEMap.end() ) + { + LLLocalTextureObject* lto = iter->second; + return lto; + } + return NULL; +} + +const LLLocalTextureObject* LLWearable::getConstLocalTextureObject(S32 index) const { te_map_t::const_iterator iter = mTEMap.find(index); if( iter != mTEMap.end() ) { - return (LLLocalTextureObject*) &iter->second; + const LLLocalTextureObject* lto = iter->second; + return lto; } return NULL; } void LLWearable::setLocalTextureObject(S32 index, LLLocalTextureObject *lto) { + if( mTEMap.find(index) != mTEMap.end() ) + { + mTEMap.erase(index); + } if( lto ) { - LLLocalTextureObject obj(*lto); - mTEMap[index] = obj; + mTEMap[index] = new LLLocalTextureObject(*lto); + } +} + + +void LLWearable::addVisualParam(LLVisualParam *param) +{ + if( mVisualParamIndexMap[param->getID()] ) + { + delete mVisualParamIndexMap[param->getID()]; + } + mVisualParamIndexMap[param->getID()] = param; +} + +void LLWearable::setVisualParams() +{ + LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); + + for (VisualParamIndexMap_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); iter++) + { + S32 id = iter->first; + LLVisualParam *wearable_param = iter->second; + F32 value = wearable_param->getWeight(); + avatar->setVisualParamWeight(id, value, FALSE); + } +} + + +void LLWearable::setVisualParamWeight(S32 param_index, F32 value, BOOL set_by_user) +{ + if( is_in_map(mVisualParamIndexMap, param_index ) ) + { + LLVisualParam *wearable_param = mVisualParamIndexMap[param_index]; + wearable_param->setWeight(value, set_by_user); } else { - mTEMap.erase(index); + llerrs << "LLWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl; + } +} + +F32 LLWearable::getVisualParamWeight(S32 param_index) const +{ + if( is_in_map(mVisualParamIndexMap, param_index ) ) + { + const LLVisualParam *wearable_param = mVisualParamIndexMap.find(param_index)->second; + return wearable_param->getWeight(); + } + else + { + llwarns << "LLWerable::getVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl; + } + return (F32)-1.0; +} + +LLVisualParam* LLWearable::getVisualParam(S32 index) const +{ + VisualParamIndexMap_t::const_iterator iter = mVisualParamIndexMap.find(index); + return (iter == mVisualParamIndexMap.end()) ? NULL : iter->second; +} + + +void LLWearable::getVisualParams(visualParamCluster_t &list) +{ + VisualParamIndexMap_t::iterator iter = mVisualParamIndexMap.begin(); + VisualParamIndexMap_t::iterator end = mVisualParamIndexMap.end(); + + // add all visual params to the passed-in vector + for( ; iter != end; ++iter ) + { + list.push_back(iter->second); + } +} + +LLColor4 LLWearable::getClothesColor(S32 te) +{ + LLColor4 color; + U32 param_name[3]; + if( LLVOAvatar::teToColorParams( (LLVOAvatarDefines::ETextureIndex)te, param_name ) ) + { + for( U8 index = 0; index < 3; index++ ) + { + color.mV[index] = getVisualParamWeight(param_name[index]); + } + } + return color; +} + +void LLWearable::setClothesColor( S32 te, const LLColor4& new_color, BOOL set_by_user ) +{ + U32 param_name[3]; + if( LLVOAvatar::teToColorParams( (LLVOAvatarDefines::ETextureIndex)te, param_name ) ) + { + for( U8 index = 0; index < 3; index++ ) + { + setVisualParamWeight(param_name[index], new_color.mV[index], set_by_user); + } + } +} + +void LLWearable::revertValues() +{ + //update saved settings so wearable is no longer dirty + for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++) + { + S32 id = iter->first; + F32 value = iter->second; + setVisualParamWeight(id, value, TRUE); + } + + syncImages(mSavedTEMap, mTEMap); + + if( gFloaterCustomize ) + { + gFloaterCustomize->updateScrollingPanelList(TRUE); } } +BOOL LLWearable::isOnTop() +{ + return (this == gAgentWearables.getTopWearable(mType)); +} + +void LLWearable::createLayers(S32 te) +{ + LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); + LLTexLayerSet *layer_set = avatar->getLayerSet((ETextureIndex)te); + if( layer_set ) + { + layer_set->cloneTemplates(mTEMap[te], (ETextureIndex)te, this); + } + else + { + llerrs << "could not find layerset for LTO in wearable!" << llendl; + } +} + +void LLWearable::saveValues() +{ + //update saved settings so wearable is no longer dirty + mSavedVisualParamMap.clear(); + for (VisualParamIndexMap_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); ++iter) + { + S32 id = iter->first; + LLVisualParam *wearable_param = iter->second; + F32 value = wearable_param->getWeight(); + mSavedVisualParamMap[id] = value; + } + + // Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed) + syncImages(mTEMap, mSavedTEMap); + + if( gFloaterCustomize ) + { + gFloaterCustomize->updateScrollingPanelList(TRUE); + } +} + +void LLWearable::syncImages(te_map_t &src, te_map_t &dst) +{ + // Deep copy of src (copies only those tes that are current, filling in defaults where needed) + for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) + { + if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) + { + te_map_t::const_iterator iter = src.find(te); + LLUUID image_id; + LLViewerFetchedTexture *image = NULL; + LLLocalTextureObject *lto = NULL; + if(iter != src.end()) + { + // there's a Local Texture Object in the source image map. Use this to populate the values to store in the destination image map. + lto = iter->second; + image = lto->getImage(); + image_id = lto->getID(); + } + else + { + // there is no Local Texture Object in the source image map. Get defaults values for populating the destination image map. + image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te); + image = LLViewerTextureManager::getFetchedTexture( image_id ); + } + + if( dst.find(te) != dst.end() ) + { + // there's already an entry in the destination map for the texture. Just update its values. + dst[te]->setImage(image); + dst[te]->setID(image_id); + } + else + { + // no entry found in the destination map, we need to create a new Local Texture Object + dst[te] = new LLLocalTextureObject(image, image_id); + } + + if( lto ) + { + // If we pulled values from a Local Texture Object in the source map, make sure the proper flags are set in the new (or updated) entry in the destination map. + dst[te]->setBakedReady(lto->getBakedReady()); + dst[te]->setDiscard(lto->getDiscard()); + } + } + } +} + +void LLWearable::destroyTextures() +{ + for( te_map_t::iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter ) + { + LLLocalTextureObject *lto = iter->second; + delete lto; + } + mTEMap.clear(); + for( te_map_t::iterator iter = mSavedTEMap.begin(); iter != mSavedTEMap.end(); ++iter ) + { + LLLocalTextureObject *lto = iter->second; + delete lto; + } + mSavedTEMap.clear(); +} + struct LLWearableSaveData { EWearableType mType; @@ -882,6 +1162,7 @@ void LLWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* userda // delete the context data delete data; + } std::ostream& operator<<(std::ostream &s, const LLWearable &w) @@ -893,11 +1174,12 @@ std::ostream& operator<<(std::ostream &s, const LLWearable &w) //w.mSaleInfo s << " Params:" << "\n"; - for (LLWearable::param_map_t::const_iterator iter = w.mVisualParamMap.begin(); - iter != w.mVisualParamMap.end(); ++iter) + for (LLWearable::VisualParamIndexMap_t::const_iterator iter = w.mVisualParamIndexMap.begin(); + iter != w.mVisualParamIndexMap.end(); ++iter) { S32 param_id = iter->first; - F32 param_weight = iter->second; + LLVisualParam *wearable_param = iter->second; + F32 param_weight = wearable_param->getWeight(); s << " " << param_id << " " << param_weight << "\n"; } @@ -906,7 +1188,7 @@ std::ostream& operator<<(std::ostream &s, const LLWearable &w) iter != w.mTEMap.end(); ++iter) { S32 te = iter->first; - const LLUUID& image_id = iter->second.getID(); + const LLUUID& image_id = iter->second->getID(); s << " " << te << " " << image_id << "\n"; } return s; diff --git a/indra/newview/llwearable.h b/indra/newview/llwearable.h index d7b4d3f91e..201f4f91ef 100644 --- a/indra/newview/llwearable.h +++ b/indra/newview/llwearable.h @@ -43,6 +43,9 @@ #include "lllocaltextureobject.h" class LLViewerInventoryItem; +class LLVisualParam; +class LLTexGlobalColorInfo; +class LLTexGlobalColor; class LLWearable { @@ -66,7 +69,7 @@ public: const LLAssetID& getAssetID() const { return mAssetID; } const LLTransactionID& getTransactionID() const { return mTransactionID; } EWearableType getType() const { return mType; } - void setType(EWearableType type) { mType = type; } + void setType(EWearableType type); const std::string& getName() const { return mName; } void setName(const std::string& name) { mName = name; } const std::string& getDescription() const { return mDescription; } @@ -81,11 +84,12 @@ public: LLLocalTextureObject* getLocalTextureObject(S32 index) const; public: + typedef std::vector<LLVisualParam*> visualParamCluster_t; + BOOL isDirty() const; BOOL isOldVersion() const; - void writeToAvatar( BOOL set_by_user ); - void readFromAvatar(); + void writeToAvatar( BOOL set_by_user, BOOL update_customize_floater = TRUE ); void removeFromAvatar( BOOL set_by_user ) { LLWearable::removeFromAvatar( mType, set_by_user ); } static void removeFromAvatar( EWearableType type, BOOL set_by_user ); @@ -104,9 +108,36 @@ public: friend std::ostream& operator<<(std::ostream &s, const LLWearable &w); void setItemID(const LLUUID& item_id); + + LLLocalTextureObject* getLocalTextureObject(S32 index); + const LLLocalTextureObject* getConstLocalTextureObject(S32 index) const; + void setLocalTextureObject(S32 index, LLLocalTextureObject *lto); + void addVisualParam(LLVisualParam *param); + void setVisualParams(); + void setVisualParamWeight(S32 index, F32 value, BOOL set_by_user); + F32 getVisualParamWeight(S32 index) const; + LLVisualParam* getVisualParam(S32 index) const; + void getVisualParams(visualParamCluster_t &list); + + LLColor4 getClothesColor(S32 te); + void setClothesColor( S32 te, const LLColor4& new_color, BOOL set_by_user ); + + void revertValues(); + + BOOL isOnTop(); + private: + typedef std::map<S32, LLLocalTextureObject*> te_map_t; + typedef std::map<S32, LLVisualParam *> VisualParamIndexMap_t; + + void createLayers(S32 te); + void createVisualParams(); + void saveValues(); + void syncImages(te_map_t &src, te_map_t &dst); + void destroyTextures(); + 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; @@ -118,9 +149,12 @@ private: EWearableType mType; typedef std::map<S32, F32> param_map_t; - param_map_t mVisualParamMap; // maps visual param id to weight - typedef std::map<S32, LLLocalTextureObject> te_map_t; + param_map_t mSavedVisualParamMap; // last saved version of visual params + + VisualParamIndexMap_t mVisualParamIndexMap; + te_map_t mTEMap; // maps TE to LocalTextureObject + te_map_t mSavedTEMap; // last saved version of TEMap LLUUID mItemID; // ID of the inventory item in the agent's inventory }; diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp index 1275312676..0257329dc1 100644 --- a/indra/newview/llwearablelist.cpp +++ b/indra/newview/llwearablelist.cpp @@ -218,38 +218,19 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID } -LLWearable* LLWearableList::createCopyFromAvatar(const LLWearable* old_wearable, const std::string& new_name) -{ - lldebugs << "LLWearableList::createCopyFromAvatar()" << llendl; - - LLWearable *wearable = generateNewWearable(); - wearable->copyDataFrom( old_wearable ); - - LLPermissions perm(old_wearable->getPermissions()); - perm.setOwnerAndGroup(LLUUID::null, gAgent.getID(), LLUUID::null, true); - wearable->setPermissions(perm); - wearable->readFromAvatar(); // update from the avatar - - if (!new_name.empty()) wearable->setName(new_name); - - // Send to the dataserver - wearable->saveNewAsset(); - - return wearable; -} - - -LLWearable* LLWearableList::createCopy(const LLWearable* old_wearable) +LLWearable* LLWearableList::createCopy(const LLWearable* old_wearable, const std::string& new_name) { lldebugs << "LLWearableList::createCopy()" << llendl; LLWearable *wearable = generateNewWearable(); wearable->copyDataFrom(old_wearable); - + LLPermissions perm(old_wearable->getPermissions()); perm.setOwnerAndGroup(LLUUID::null, gAgent.getID(), LLUUID::null, true); wearable->setPermissions(perm); + if (!new_name.empty()) wearable->setName(new_name); + // Send to the dataserver wearable->saveNewAsset(); @@ -273,7 +254,6 @@ LLWearable* LLWearableList::createNewWearable( EWearableType type ) wearable->setPermissions(perm); // Description and sale info have default values. - wearable->setParamsToDefaults(); wearable->setTexturesToDefaults(); diff --git a/indra/newview/llwearablelist.h b/indra/newview/llwearablelist.h index f844c0f443..e5155c66a4 100644 --- a/indra/newview/llwearablelist.h +++ b/indra/newview/llwearablelist.h @@ -53,8 +53,7 @@ public: void(*asset_arrived_callback)(LLWearable*, void* userdata), void* userdata); - LLWearable* createCopyFromAvatar(const LLWearable* old_wearable, const std::string& new_name = std::string()); - LLWearable* createCopy(const LLWearable* old_wearable); + LLWearable* createCopy(const LLWearable* old_wearable, const std::string& new_name = std::string()); LLWearable* createNewWearable(EWearableType type); // Callback diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index 30736b1e03..5446a08ebf 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -47,7 +47,6 @@ #include "llcallingcard.h" #include "llviewercontrol.h" #include "llcylinder.h" -#include "llfloaterdirectory.h" #include "llfloatermap.h" #include "llfloaterworldmap.h" #include "llfocusmgr.h" diff --git a/indra/newview/macview_Prefix.h b/indra/newview/macview_Prefix.h index 0fcdf2da4f..a71362a139 100644 --- a/indra/newview/macview_Prefix.h +++ b/indra/newview/macview_Prefix.h @@ -66,7 +66,6 @@ #include "llfloaterbuildoptions.h" #include "llfloaterchat.h" #include "llfloatercustomize.h" -#include "llfloaterdirectory.h" #include "llfloatergroups.h" #include "llfloaterworldmap.h" #include "llfloatermute.h" diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 3800b9223d..b50e71bf48 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -3872,44 +3872,48 @@ void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects, BOOL render iter != avatarp->mAttachmentPoints.end(); ) { LLVOAvatar::attachment_map_t::iterator curiter = iter++; - LLViewerJointAttachment* attachmentp = curiter->second; - if (attachmentp->getIsHUDAttachment()) + LLViewerJointAttachment* attachment = curiter->second; + if (attachment->getIsHUDAttachment()) { - LLViewerObject* objectp = attachmentp->getObject(); - if (objectp) + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) { - LLDrawable* drawable = objectp->mDrawable; - if (drawable->isDead()) + if (LLViewerObject* attached_object = (*attachment_iter)) { - continue; - } - - for (S32 j = 0; j < drawable->getNumFaces(); ++j) - { - LLFace* facep = drawable->getFace(j); - if (!facep->getPool()) + LLDrawable* drawable = attached_object->mDrawable; + if (drawable->isDead()) { - facep->renderForSelect(prim_mask); + continue; } - } - - //render child faces - LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++) - { - LLViewerObject* child = *iter; - LLDrawable* child_drawable = child->mDrawable; - for (S32 l = 0; l < child_drawable->getNumFaces(); ++l) + + for (S32 j = 0; j < drawable->getNumFaces(); ++j) { - LLFace* facep = child_drawable->getFace(l); + LLFace* facep = drawable->getFace(j); if (!facep->getPool()) { facep->renderForSelect(prim_mask); } } + + //render child faces + LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++) + { + LLViewerObject* child = *iter; + LLDrawable* child_drawable = child->mDrawable; + for (S32 l = 0; l < child_drawable->getNumFaces(); ++l) + { + LLFace* facep = child_drawable->getFace(l); + if (!facep->getPool()) + { + facep->renderForSelect(prim_mask); + } + } + } } - } + } } } @@ -8682,10 +8686,15 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) iter != avatar->mAttachmentPoints.end(); ++iter) { - LLViewerObject* object = iter->second->getObject(); - if (object) + LLViewerJointAttachment *attachment = iter->second; + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) { - markVisible(object->mDrawable->getSpatialBridge(), *LLViewerCamera::getInstance()); + if (LLViewerObject* attached_object = (*attachment_iter)) + { + markVisible(attached_object->mDrawable->getSpatialBridge(), *LLViewerCamera::getInstance()); + } } } diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 4d8f88c80b..e2cc1481c4 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -567,7 +567,7 @@ reference="White_05" /> <color name="ScrollDisabledColor" - reference="Unused?" /> + reference="White_25" /> <color name="ScrollHighlightedColor" reference="Unused?" /> diff --git a/indra/newview/skins/default/html/da/loading/loading.html b/indra/newview/skins/default/html/da/loading/loading.html new file mode 100644 index 0000000000..cdad5702b9 --- /dev/null +++ b/indra/newview/skins/default/html/da/loading/loading.html @@ -0,0 +1,10 @@ +<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/> Indlæser...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/de/loading/loading.html b/indra/newview/skins/default/html/de/loading/loading.html new file mode 100644 index 0000000000..3eddbc24f5 --- /dev/null +++ b/indra/newview/skins/default/html/de/loading/loading.html @@ -0,0 +1,10 @@ +<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/> Wird geladen...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/es/loading/loading.html b/indra/newview/skins/default/html/es/loading/loading.html new file mode 100644 index 0000000000..f03284ba8c --- /dev/null +++ b/indra/newview/skins/default/html/es/loading/loading.html @@ -0,0 +1,10 @@ +<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/> Cargando...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/fr/loading/loading.html b/indra/newview/skins/default/html/fr/loading/loading.html new file mode 100644 index 0000000000..23c0ef03bc --- /dev/null +++ b/indra/newview/skins/default/html/fr/loading/loading.html @@ -0,0 +1,10 @@ +<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/> Chargement...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/hu/loading/loading.html b/indra/newview/skins/default/html/hu/loading/loading.html new file mode 100644 index 0000000000..ade91f76c2 --- /dev/null +++ b/indra/newview/skins/default/html/hu/loading/loading.html @@ -0,0 +1,10 @@ +<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/> Betöltés folyamatban...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/it/loading/loading.html b/indra/newview/skins/default/html/it/loading/loading.html new file mode 100644 index 0000000000..0f9af31f6e --- /dev/null +++ b/indra/newview/skins/default/html/it/loading/loading.html @@ -0,0 +1,10 @@ +<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/> Attendi...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/ja/loading-error/index.html b/indra/newview/skins/default/html/ja/loading-error/index.html index e0bcc94b6b..d969c03098 100644 --- a/indra/newview/skins/default/html/ja/loading-error/index.html +++ b/indra/newview/skins/default/html/ja/loading-error/index.html @@ -18,7 +18,7 @@ a:hover {color:#ff7900;text-decoration:underline;} <body> <div id="infobox"> <img src="../../unabletoconnect.png"><br/> <p> Second Lifeによるログインサーバーへの接続が確立できません。 </p> - <p> インターネット接続を確認してください。 お使いのコンピュータやネットワークがファイヤウォールまたはプロキシにより保護されている場合は、Second Lifeによるネットワークへのアクセスが許可されていることを確認してください。 + <p> インターネット接続を確認してください。 お使いのコンピュータやネットワークがファイヤウォールまたはプロキシにより保護されている場合は、Second Lifeによるネットワークへのアクセスが許可されていることを確認してください。 </p> <div id="submitbtn"> <input class="input_over" type="submit" value="もう一度試す" onclick="document.location='secondlife:///app/login_refresh'; this.className='pressed';" onmouseover="this.className='input_over';" onmouseout="this.className='input_off';" /> </div> </div> </div> diff --git a/indra/newview/skins/default/html/ja/loading/loading.html b/indra/newview/skins/default/html/ja/loading/loading.html new file mode 100644 index 0000000000..069dc5d12f --- /dev/null +++ b/indra/newview/skins/default/html/ja/loading/loading.html @@ -0,0 +1,10 @@ +<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/> ロード中...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/nl/loading/loading.html b/indra/newview/skins/default/html/nl/loading/loading.html new file mode 100644 index 0000000000..39a8691f3f --- /dev/null +++ b/indra/newview/skins/default/html/nl/loading/loading.html @@ -0,0 +1,10 @@ +<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/> Laden...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/pl/loading/loading.html b/indra/newview/skins/default/html/pl/loading/loading.html new file mode 100644 index 0000000000..515890c2d5 --- /dev/null +++ b/indra/newview/skins/default/html/pl/loading/loading.html @@ -0,0 +1,10 @@ +<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/> Ładowanie...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/pt/loading/loading.html b/indra/newview/skins/default/html/pt/loading/loading.html new file mode 100644 index 0000000000..635ea62406 --- /dev/null +++ b/indra/newview/skins/default/html/pt/loading/loading.html @@ -0,0 +1,10 @@ +<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/> Carregando...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/ru/loading/loading.html b/indra/newview/skins/default/html/ru/loading/loading.html new file mode 100644 index 0000000000..dcc0d73c1a --- /dev/null +++ b/indra/newview/skins/default/html/ru/loading/loading.html @@ -0,0 +1,10 @@ +<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/> Загрузка...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/tr/loading/loading.html b/indra/newview/skins/default/html/tr/loading/loading.html new file mode 100644 index 0000000000..e7812e7c8e --- /dev/null +++ b/indra/newview/skins/default/html/tr/loading/loading.html @@ -0,0 +1,10 @@ +<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/> Yükleniyor...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/uk/loading/loading.html b/indra/newview/skins/default/html/uk/loading/loading.html new file mode 100644 index 0000000000..0f67994635 --- /dev/null +++ b/indra/newview/skins/default/html/uk/loading/loading.html @@ -0,0 +1,10 @@ +<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/> Завантаж...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/zh/loading-error/index.html b/indra/newview/skins/default/html/zh/loading-error/index.html index 01cdec94fe..97201318ff 100644 --- a/indra/newview/skins/default/html/zh/loading-error/index.html +++ b/indra/newview/skins/default/html/zh/loading-error/index.html @@ -16,9 +16,9 @@ a:hover {color:#ff7900;text-decoration:underline;} </style> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head> <body> <div id="infobox"> <img src="../../unabletoconnect.png"><br/> - <p> 第二人生无法与登录服务器连接。 + <p> Second Life无法与登录服务器连接。 </p> - <p> 请检查您的因特网连接 如果您的计算机或网络由防火墙或代理器保护,请确认第二人生能在该网络里访问因特网。 + <p> 请检查您的因特网连接 如果您的计算机或网络由防火墙或代理器保护,请确认Second Life能在该网络里访问因特网。 </p> <div id="submitbtn"> <input class="input_over" type="submit" value="请再试一次" onclick="document.location='secondlife:///app/login_refresh'; this.className='pressed';" onmouseover="this.className='input_over';" onmouseout="this.className='input_off';" /> </div> </div> </div> diff --git a/indra/newview/skins/default/html/zh/loading/loading.html b/indra/newview/skins/default/html/zh/loading/loading.html new file mode 100644 index 0000000000..462ea291d9 --- /dev/null +++ b/indra/newview/skins/default/html/zh/loading/loading.html @@ -0,0 +1,10 @@ +<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/> 请等待...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/textures/map_avatar_8.tga b/indra/newview/skins/default/textures/map_avatar_8.tga Binary files differindex 28552f2237..47c8cbed6f 100644 --- a/indra/newview/skins/default/textures/map_avatar_8.tga +++ b/indra/newview/skins/default/textures/map_avatar_8.tga diff --git a/indra/newview/skins/default/textures/navbar/Search.png b/indra/newview/skins/default/textures/navbar/Search.png Binary files differindex c43519d5f1..0d0e330bc7 100644 --- a/indra/newview/skins/default/textures/navbar/Search.png +++ b/indra/newview/skins/default/textures/navbar/Search.png diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index 1f366f6c52..072fafd06e 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -1560,7 +1560,7 @@ Only large parcels can be listed in search. layout="topleft" left_pad="5" name="Clear" - tool_tip="Clear the landing point." + tool_tip="Clear the landing point" top_delta="0" width="50" /> <text @@ -1580,7 +1580,7 @@ Only large parcels can be listed in search. layout="topleft" left_delta="116" name="landing type" - tool_tip="Teleport Routing -- select how to handle teleports onto your land." + tool_tip="Teleport Routing -- select how to handle teleports onto your land" top_delta="0" width="120"> <combo_box.item diff --git a/indra/newview/skins/default/xui/en/floater_animation_preview.xml b/indra/newview/skins/default/xui/en/floater_animation_preview.xml index 3a2337bfff..a6a6e0ec22 100644 --- a/indra/newview/skins/default/xui/en/floater_animation_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_animation_preview.xml @@ -196,7 +196,7 @@ Maximum animation length is [MAX_LENGTH] seconds. left="10" max_val="4" name="priority" - tool_tip="Controls which other animations can be overridden by this animation." + tool_tip="Controls which other animations can be overridden by this animation" width="160" /> <check_box top_pad="0" @@ -206,7 +206,7 @@ Maximum animation length is [MAX_LENGTH] seconds. left="10" width="100" name="loop_check" - tool_tip="Makes this animation loop." /> + tool_tip="Makes this animation loop" /> <spinner follows="left|top" height="23" @@ -219,7 +219,7 @@ Maximum animation length is [MAX_LENGTH] seconds. left="30" max_val="100" name="loop_in_point" - tool_tip="Sets point in animation that looping returns to." + tool_tip="Sets point in animation that looping returns to" width="110" /> <spinner bottom_delta="0" @@ -232,7 +232,7 @@ Maximum animation length is [MAX_LENGTH] seconds. left_pad="10" max_val="100" name="loop_out_point" - tool_tip="Sets point in animation that ends a loop." + tool_tip="Sets point in animation that ends a loop" label_width="45" width="120" /> <text @@ -252,7 +252,7 @@ Maximum animation length is [MAX_LENGTH] seconds. layout="topleft" left_pad="0" name="hand_pose_combo" - tool_tip="Controls what hands do during animation." + tool_tip="Controls what hands do during animation" width="150"> <combo_box.item label="Spread" @@ -325,7 +325,7 @@ Maximum animation length is [MAX_LENGTH] seconds. layout="topleft" left_pad="0" name="emote_combo" - tool_tip="Controls what face does during animation."> + tool_tip="Controls what face does during animation"> <combo_box.item label="(None)" name="[None]" /> @@ -405,7 +405,7 @@ Maximum animation length is [MAX_LENGTH] seconds. layout="topleft" left_pad="0" name="preview_base_anim" - tool_tip="Use this to test your animation behavior while your avatar performs common actions."> + tool_tip="Use this to test your animation behavior while your avatar performs common actions"> <combo_box.item label="Standing" name="Standing" /> @@ -430,7 +430,7 @@ Maximum animation length is [MAX_LENGTH] seconds. left="10" max_val="10" name="ease_in_time" - tool_tip="Amount of time (in seconds) over which animations blends in." + tool_tip="Amount of time (in seconds) over which animations blends in" top_pad="10" width="200" /> <spinner @@ -444,7 +444,7 @@ Maximum animation length is [MAX_LENGTH] seconds. top_pad="0" max_val="10" name="ease_out_time" - tool_tip="Amount of time (in seconds) over which animations blends out." + tool_tip="Amount of time (in seconds) over which animations blends out" width="200" /> <button follows="top|right" @@ -455,7 +455,7 @@ Maximum animation length is [MAX_LENGTH] seconds. left="10" name="play_btn" picture_style="true" - tool_tip="Play/pause your animation." + tool_tip="Play/pause your animation" top_pad="0" width="28" /> <button diff --git a/indra/newview/skins/default/xui/en/floater_beacons.xml b/indra/newview/skins/default/xui/en/floater_beacons.xml index 09b1735e04..a60064fb37 100644 --- a/indra/newview/skins/default/xui/en/floater_beacons.xml +++ b/indra/newview/skins/default/xui/en/floater_beacons.xml @@ -53,7 +53,7 @@ height="16" layout="topleft" left="20" - tool_tip="Beacon Width" + tool_tip="Beacon width" name="beacon_width_label" top_pad="3" width="128"> diff --git a/indra/newview/skins/default/xui/en/floater_build_options.xml b/indra/newview/skins/default/xui/en/floater_build_options.xml index 42a063928c..3e6845cfa5 100644 --- a/indra/newview/skins/default/xui/en/floater_build_options.xml +++ b/indra/newview/skins/default/xui/en/floater_build_options.xml @@ -61,7 +61,7 @@ height="16" layout="topleft" left="10" - tool_tip="Grid Opacity" + tool_tip="Grid opacity" name="grid_opacity_label" top_pad="5" width="128"> diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency.xml b/indra/newview/skins/default/xui/en/floater_buy_currency.xml index 041cd2a118..5bab421adf 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_currency.xml @@ -28,7 +28,7 @@ layout="topleft" left="20" height="30" - top="30" + top="25" width="300" name="info_need_more"> You need more L$ @@ -53,7 +53,7 @@ layout="topleft" left="20" height="30" - top="30" + top="25" width="200" name="info_buying"> Buy L$ @@ -67,7 +67,7 @@ layout="topleft" left="20" name="balance_label" - top="70" + top="65" width="210"> I have </text> @@ -91,7 +91,7 @@ follows="top|left" font="SansSerifMedium" height="16" - top="100" + top="95" layout="topleft" left="20" name="currency_action" @@ -133,7 +133,7 @@ height="16" layout="topleft" left="20" - top="130" + top="125" name="buying_label" width="210"> For the price @@ -148,10 +148,10 @@ height="16" top_delta="0" layout="topleft" - left="170" + left="150" name="currency_est" - width="150"> - [LOCALAMOUNT] + width="170"> + approx. [LOCALAMOUNT] </text> <text type="string" @@ -161,7 +161,7 @@ follows="top|left" height="16" layout="topleft" - top="130" + top="125" left="170" width="150" halign="right" @@ -171,11 +171,11 @@ <text type="string" font="SansSerifSmall" - top="150" + top="145" length="1" follows="top|left" - halign="right" height="16" + halign="right" left="150" width="170" layout="topleft" @@ -191,7 +191,7 @@ layout="topleft" left="20" name="total_label" - top="170" + top="165" width="210"> My new balance will be </text> @@ -212,28 +212,58 @@ <text type="string" length="1" + text_color="0.7 0.7 0.7 0.5" + follows="top|left" + layout="topleft" + halign="right" + top="189" + left="20" + width="300" + height="30" + name="currency_links"> + [http://www.secondlife.com/ payment method] | [http://www.secondlife.com/ currency] | [http://www.secondlife.com exchange rate] + </text> + <text + type="string" + length="1" + text_color="0.7 0.7 0.7 0.5" follows="top|left" layout="topleft" - top="195" + halign="right" + top="202" left="20" width="300" height="30" + name="exchange_rate_note"> +Re-enter amount to see the latest exchange rate. + </text> + <text + type="string" + length="1" + text_color="0.7 0.7 0.7 0.5" + follows="top|left" + layout="topleft" + halign="right" + top="213" + left="10" + width="310" + height="30" name="purchase_warning_repurchase"> - Confirming this purchase only buys the L$. -You'll need to try again. + Confirming this purchase only buys L$, not the object. </text> <text type="string" length="1" + text_color="0.7 0.7 0.7 0.5" follows="top|left" layout="topleft" - top="195" + halign="right" + top="213" left="20" width="300" height="30" name="purchase_warning_notenough"> - You aren't buying enough L$. -Increase the amount to buy. + You aren't buying enough L$. Increase the amount. </text> <button diff --git a/indra/newview/skins/default/xui/en/floater_camera.xml b/indra/newview/skins/default/xui/en/floater_camera.xml index 86c75a3946..a5c73a7ca4 100644 --- a/indra/newview/skins/default/xui/en/floater_camera.xml +++ b/indra/newview/skins/default/xui/en/floater_camera.xml @@ -45,7 +45,7 @@ quadrant="left" scale_image="false" sound_flags="3" - tool_tip="Orbit Camera Around Focus" + tool_tip="Orbit camera around focus" top="15" width="64" /> <joystick_track @@ -60,7 +60,7 @@ quadrant="left" scale_image="false" sound_flags="3" - tool_tip="Move Camera Up and Down, Left and Right" + tool_tip="Move camera up and down, left and right" top="15" visible="false" width="64" /> @@ -77,7 +77,7 @@ quadrant="left" scale_image="false" sound_flags="3" - tool_tip="Zoom Camera Towards Focus" + tool_tip="Zoom camera toward focus" top_delta="0" width="16" /> </panel> @@ -99,7 +99,7 @@ image_selected="PushButton_Selected_Press" name="orbit_btn" tab_stop="false" - tool_tip="Orbit Camera" + tool_tip="Orbit camera" value="true" width="25"> </button> @@ -113,7 +113,7 @@ image_selected="PushButton_Selected_Press" name="pan_btn" tab_stop="false" - tool_tip="Pan Camera" + tool_tip="Pan camera" width="25"> </button> <button @@ -125,7 +125,7 @@ image_selected="PushButton_Selected_Press" name="avatarview_btn" tab_stop="false" - tool_tip="See as Avatar" + tool_tip="See as avatar" width="25"> </button> <button @@ -138,7 +138,7 @@ image_selected="PushButton_Selected_Press" name="freecamera_btn" tab_stop="false" - tool_tip="View Object" + tool_tip="View object" width="25"> </button> diff --git a/indra/newview/skins/default/xui/en/floater_customize.xml b/indra/newview/skins/default/xui/en/floater_customize.xml index 3b6d5452e3..70468e7474 100644 --- a/indra/newview/skins/default/xui/en/floater_customize.xml +++ b/indra/newview/skins/default/xui/en/floater_customize.xml @@ -1039,7 +1039,7 @@ scratch and wear it. layout="topleft" left_delta="0" name="Color/Tint" - tool_tip="Click to open Color Picker" + tool_tip="Click to open color picker" top_delta="80" width="64" /> <button @@ -1156,21 +1156,6 @@ scratch and wear it. 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" @@ -1260,7 +1245,7 @@ scratch and wear it. layout="topleft" left_delta="0" name="Color/Tint" - tool_tip="Click to open Color Picker" + tool_tip="Click to open color picker" top_delta="80" width="64" /> <button @@ -1377,21 +1362,6 @@ scratch and wear it. 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" @@ -1524,21 +1494,6 @@ scratch and wear it. 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" @@ -1600,7 +1555,7 @@ scratch and wear it. layout="topleft" left_delta="0" name="Color/Tint" - tool_tip="Click to open Color Picker" + tool_tip="Click to open color picker" top_delta="80" width="64" /> <button @@ -1745,21 +1700,6 @@ scratch and wear it. 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" @@ -1821,7 +1761,7 @@ scratch and wear it. layout="topleft" left_delta="0" name="Color/Tint" - tool_tip="Click to open Color Picker" + tool_tip="Click to open color picker" top_delta="80" width="64" /> <button @@ -1966,21 +1906,6 @@ scratch and wear it. 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" @@ -2054,7 +1979,7 @@ scratch and wear it. layout="topleft" left_delta="0" name="Color/Tint" - tool_tip="Click to open Color Picker" + tool_tip="Click to open color picker" top_delta="80" width="64" /> <button @@ -2199,21 +2124,6 @@ scratch and wear it. 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" @@ -2275,7 +2185,7 @@ scratch and wear it. layout="topleft" left_delta="0" name="Color/Tint" - tool_tip="Click to open Color Picker" + tool_tip="Click to open color picker" top_delta="80" width="64" /> <button @@ -2420,21 +2330,6 @@ scratch and wear it. 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" @@ -2496,7 +2391,7 @@ scratch and wear it. layout="topleft" left_delta="0" name="Color/Tint" - tool_tip="Click to open Color Picker" + tool_tip="Click to open color picker" top_delta="80" width="64" /> <button @@ -2641,21 +2536,6 @@ scratch and wear it. 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" @@ -2717,7 +2597,7 @@ scratch and wear it. layout="topleft" left_delta="0" name="Color/Tint" - tool_tip="Click to open Color Picker" + tool_tip="Click to open color picker" top_delta="80" width="64" /> <button @@ -2862,21 +2742,6 @@ scratch and wear it. 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" @@ -2938,7 +2803,7 @@ scratch and wear it. layout="topleft" left_delta="0" name="Color/Tint" - tool_tip="Click to open Color Picker" + tool_tip="Click to open color picker" top_delta="80" width="64" /> <button @@ -3083,21 +2948,6 @@ scratch and wear it. 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" @@ -3385,21 +3235,6 @@ scratch and wear it. 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" diff --git a/indra/newview/skins/default/xui/en/floater_env_settings.xml b/indra/newview/skins/default/xui/en/floater_env_settings.xml index 5e87e065a4..cecd6c4ef7 100644 --- a/indra/newview/skins/default/xui/en/floater_env_settings.xml +++ b/indra/newview/skins/default/xui/en/floater_env_settings.xml @@ -105,7 +105,7 @@ layout="topleft" left="390" name="EnvWaterColor" - tool_tip="Click to open Color Picker" + tool_tip="Click to open color picker" top="30" width="40" /> <text diff --git a/indra/newview/skins/default/xui/en/floater_gesture.xml b/indra/newview/skins/default/xui/en/floater_gesture.xml index 3d0a969112..7346c81e79 100644 --- a/indra/newview/skins/default/xui/en/floater_gesture.xml +++ b/indra/newview/skins/default/xui/en/floater_gesture.xml @@ -59,7 +59,7 @@ <button follows="bottom|left" font="SansSerifBigBold" - tool_tip="Change sort and view of Recent Residents list" + tool_tip="Change sort and view of recent residents list" height="18" image_disabled="OptionsMenu_Disabled" image_selected="OptionsMenu_Press" @@ -81,7 +81,7 @@ left_pad="5" name="new_gesture_btn" picture_style="true" - tool_tip="Make new Gesture" + tool_tip="Make new gesture" top_delta="0" width="18" /> <button @@ -95,7 +95,7 @@ left_pad="230" name="del_btn" picture_style="true" - tool_tip="Delete this Gesture" + tool_tip="Delete this gesture" top_delta="0" width="18" /> </panel> diff --git a/indra/newview/skins/default/xui/en/floater_god_tools.xml b/indra/newview/skins/default/xui/en/floater_god_tools.xml index 53d05f3c61..02754b25dd 100644 --- a/indra/newview/skins/default/xui/en/floater_god_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_god_tools.xml @@ -98,7 +98,7 @@ layout="topleft" left="10" name="check prelude" - tool_tip="Set this to make the region a prelude." + tool_tip="Set this to make the region a prelude" top_pad="10" width="180"> <check_box.commit_callback @@ -110,7 +110,7 @@ layout="topleft" left_delta="0" name="check fixed sun" - tool_tip="Fix the sun position (like in Region/Estate > Terrain." + tool_tip="Fix the sun position (like in Region/Estate > Terrain" top_pad="4" width="180"> <check_box.commit_callback @@ -134,7 +134,7 @@ layout="topleft" left_delta="0" name="check visible" - tool_tip="Set this to make the region visible to non-gods." + tool_tip="Set this to make the region visible to non-gods" top_pad="4" width="180"> <check_box.commit_callback @@ -146,7 +146,7 @@ layout="topleft" left_delta="0" name="check damage" - tool_tip="Set this to enable damage in this region." + tool_tip="Set this to enable damage in this region" top_pad="4" width="180"> <check_box.commit_callback @@ -158,7 +158,7 @@ layout="topleft" left_delta="0" name="block dwell" - tool_tip="Set this to make the region not compute traffic." + tool_tip="Set this to make the region not compute traffic" top_pad="4" width="180"> <check_box.commit_callback @@ -182,7 +182,7 @@ layout="topleft" left_delta="0" name="is sandbox" - tool_tip="Toggle whether this is a sandbox region." + tool_tip="Toggle whether this is a sandbox region" top_pad="4" width="180"> <check_box.commit_callback @@ -197,7 +197,7 @@ layout="topleft" left="12" name="Bake Terrain" - tool_tip="Save the current terrain as default." + tool_tip="Save the current terrain as default" top_pad="32" width="110"> <button.commit_callback @@ -211,7 +211,7 @@ label_selected="Revert Terrain" layout="topleft" name="Revert Terrain" - tool_tip="Replace the current terrain with default." + tool_tip="Replace the current terrain with default" top_pad="10" width="110"> <button.commit_callback @@ -225,7 +225,7 @@ label_selected="Swap Terrain" layout="topleft" name="Swap Terrain" - tool_tip="Swap current terrain with default." + tool_tip="Swap current terrain with default" top_pad="10" width="110"> <button.commit_callback @@ -425,7 +425,7 @@ layout="topleft" left="278" name="Refresh" - tool_tip="Click here to refresh the above information." + tool_tip="Click here to refresh the above information" top_pad="10" width="110"> <button.commit_callback @@ -440,7 +440,7 @@ layout="topleft" left="278" name="Apply" - tool_tip="Click here to apply any changes from above." + tool_tip="Click here to apply any changes from above" top="317" width="110"> <button.commit_callback @@ -455,7 +455,7 @@ layout="topleft" left="130" name="Select Region" - tool_tip="Select the whole region with the land tool." + tool_tip="Select the whole region with the land tool" top="238" width="110"> <button.commit_callback @@ -470,7 +470,7 @@ layout="topleft" left_delta="0" name="Autosave now" - tool_tip="Save gzipped state to autosave directory." + tool_tip="Save gzipped state to autosave directory" top_pad="10" width="110"> <button.commit_callback @@ -562,7 +562,7 @@ layout="topleft" left="278" name="Apply" - tool_tip="Click here to apply any changes from above." + tool_tip="Click here to apply any changes from above" top="54" width="110"> <button.commit_callback @@ -577,7 +577,7 @@ layout="topleft" left="8" name="Set Target" - tool_tip="Set the target avatar for object deletion." + tool_tip="Set the target avatar for object deletion" top="78" width="110"> <button.commit_callback @@ -649,7 +649,7 @@ layout="topleft" left="12" name="Get Top Colliders" - tool_tip="Gets list of objects experiencing the most narrowphase callbacks." + tool_tip="Gets list of objects experiencing the most narrowphase callbacks" top_pad="20" width="130"> <button.commit_callback @@ -664,7 +664,7 @@ layout="topleft" left_delta="0" name="Get Top Scripts" - tool_tip="Gets list of objects spending the most time running scripts." + tool_tip="Gets list of objects spending the most time running scripts" top_pad="5" width="130"> <button.commit_callback @@ -679,7 +679,7 @@ layout="topleft" left_delta="0" name="Scripts digest" - tool_tip="Gets a list of all scripts and number of occurences of each." + tool_tip="Gets a list of all scripts and number of occurences of each" top_pad="5" width="130" > <button.commit_callback diff --git a/indra/newview/skins/default/xui/en/floater_hardware_settings.xml b/indra/newview/skins/default/xui/en/floater_hardware_settings.xml index c695753ca3..fe04d1f627 100644 --- a/indra/newview/skins/default/xui/en/floater_hardware_settings.xml +++ b/indra/newview/skins/default/xui/en/floater_hardware_settings.xml @@ -132,7 +132,7 @@ 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." + 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 diff --git a/indra/newview/skins/default/xui/en/floater_lagmeter.xml b/indra/newview/skins/default/xui/en/floater_lagmeter.xml index 2a431edcdd..2966b47232 100644 --- a/indra/newview/skins/default/xui/en/floater_lagmeter.xml +++ b/indra/newview/skins/default/xui/en/floater_lagmeter.xml @@ -202,7 +202,7 @@ Client </text> <text - visiblity_control="LagMeterShrunk" + invisiblity_control="LagMeterShrunk" type="string" length="1" bottom="40" @@ -216,7 +216,7 @@ Normal </text> <text - visiblity_control="LagMeterShrunk" + invisiblity_control="LagMeterShrunk" bottom="56" follows="left|top" height="16" @@ -251,7 +251,7 @@ Network </text> <text - visiblity_control="LagMeterShrunk" + invisiblity_control="LagMeterShrunk" type="string" length="1" bottom="80" @@ -265,7 +265,7 @@ Normal </text> <text - visiblity_control="LagMeterShrunk" + invisiblity_control="LagMeterShrunk" bottom="96" follows="left|top" height="16" @@ -300,7 +300,7 @@ Server </text> <text - visiblity_control="LagMeterShrunk" + invisiblity_control="LagMeterShrunk" type="string" length="1" bottom="120" @@ -314,7 +314,7 @@ Normal </text> <text - visiblity_control="LagMeterShrunk" + invisiblity_control="LagMeterShrunk" bottom="136" follows="left|top" height="16" @@ -338,6 +338,7 @@ layout="topleft" left="10" name="minimize" + tool_tip="Toggle floater size" top_delta="4" width="40"> <button.commit_callback diff --git a/indra/newview/skins/default/xui/en/floater_land_holdings.xml b/indra/newview/skins/default/xui/en/floater_land_holdings.xml index f887b48ed0..dbafa56035 100644 --- a/indra/newview/skins/default/xui/en/floater_land_holdings.xml +++ b/indra/newview/skins/default/xui/en/floater_land_holdings.xml @@ -58,7 +58,7 @@ layout="topleft" left_pad="4" name="Show on Map" - tool_tip="Show this land on the world map." + tool_tip="Show this land on the world map" top_delta="0" width="100" /> <text diff --git a/indra/newview/skins/default/xui/en/floater_moveview.xml b/indra/newview/skins/default/xui/en/floater_moveview.xml index f82e01dd1f..745385f153 100644 --- a/indra/newview/skins/default/xui/en/floater_moveview.xml +++ b/indra/newview/skins/default/xui/en/floater_moveview.xml @@ -57,7 +57,7 @@ name="turn left btn" picture_style="true" scale_image="false" - tool_tip="Turn Left (press Left Arrow or A)" + tool_tip="Turn left (press Left Arrow or A)" top="45" width="25" /> <button @@ -71,7 +71,7 @@ name="turn right btn" picture_style="true" scale_image="false" - tool_tip="Turn Right (press Right Arrow or D)" + tool_tip="Turn right (press Right Arrow or D)" top_delta="0" width="25" /> <button @@ -85,7 +85,7 @@ name="move up btn" picture_style="true" scale_image="false" - tool_tip="Fly Up, Press "E"" + tool_tip="Fly up, press "E"" top="14" width="25" /> <button @@ -99,7 +99,7 @@ name="move down btn" picture_style="true" scale_image="false" - tool_tip="Fly Down, Press "C"" + tool_tip="Fly down, press "C"" top_delta="0" width="20" /> <joystick_turn @@ -114,7 +114,7 @@ picture_style="true" quadrant="up" scale_image="false" - tool_tip="Walk Forward (press Up Arrow or W)" + tool_tip="Walk forward (press up arrow or W)" top_delta="10" width="21" /> <joystick_turn @@ -129,7 +129,7 @@ picture_style="true" quadrant="down" scale_image="false" - tool_tip="Walk Backward (press Down Arrow or S)" + tool_tip="Walk backward (press down arrow or S)" top_delta="30" width="21" /> </panel> @@ -152,7 +152,7 @@ name="mode_walk_btn" left="10" pad_right="0" - tool_tip="Walking Mode" + tool_tip="Walking mode" top="2" width="31" /> <button @@ -167,7 +167,7 @@ name="mode_run_btn" pad_left="0" pad_right="0" - tool_tip="Running Mode" + tool_tip="Running mode" top="2" width="31" /> <button @@ -181,7 +181,7 @@ name="mode_fly_btn" pad_left="0" pad_right="0" - tool_tip="Flying Mode" + tool_tip="Flying mode" top="2" width="31" /> <button @@ -192,7 +192,7 @@ layout="topleft" left="0" name="stop_fly_btn" - tool_tip="Stop Flying" + tool_tip="Stop flying" top="2" width="115" /> </panel> diff --git a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml index f1976afb4a..6fbfed5f60 100644 --- a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml +++ b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml @@ -30,23 +30,18 @@ color="1 1 1 1" enabled="true" image_name="closebox.tga" name="close_btn"/> </panel> - <text_editor + <chat_history allow_html="true" bg_readonly_color="ChatHistoryBgColor" bg_writeable_color="ChatHistoryBgColor" - follows="left|top|right|bottom" + follows="left|top|right" font="SansSerif" layout="topleft" - height="320" - max_length="2147483647" - name="Chat History Editor" + height="320" + name="chat_history" parse_highlights="true" - read_only="true" text_color="ChatHistoryTextColor" text_readonly_color="ChatHistoryTextColor" - bottom="0" - track_bottom="true" - width="250" - word_wrap="true" /> + width="250"/> </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 index 5756f9590e..e34b87dbba 100644 --- a/indra/newview/skins/default/xui/en/floater_preview_animation.xml +++ b/indra/newview/skins/default/xui/en/floater_preview_animation.xml @@ -43,7 +43,7 @@ layout="topleft" left="10" name="Anim play btn" - tool_tip="Play this animation so that others can see it." + tool_tip="Play this animation so that others can see it" top="47" width="125" /> <button @@ -54,7 +54,7 @@ layout="topleft" left_pad="5" name="Anim audition btn" - tool_tip="Play this animation so that only you can see it." + 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_sound.xml b/indra/newview/skins/default/xui/en/floater_preview_sound.xml index 4220655a6f..7a868a1fe9 100644 --- a/indra/newview/skins/default/xui/en/floater_preview_sound.xml +++ b/indra/newview/skins/default/xui/en/floater_preview_sound.xml @@ -44,7 +44,7 @@ sound_flags="0" top="55" left="10" - tool_tip="Play this sound so that others can hear it." + tool_tip="Play this sound so that others can hear it" width="125" /> <button follows="left|top" @@ -55,7 +55,7 @@ layout="topleft" name="Sound audition btn" sound_flags="0" - tool_tip="Play this sound so that only you can hear it." + tool_tip="Play this sound so that only you can hear it" left_pad="10" width="125" /> diff --git a/indra/newview/skins/default/xui/en/floater_preview_texture.xml b/indra/newview/skins/default/xui/en/floater_preview_texture.xml index e477b6ddb8..32f71da61a 100644 --- a/indra/newview/skins/default/xui/en/floater_preview_texture.xml +++ b/indra/newview/skins/default/xui/en/floater_preview_texture.xml @@ -108,10 +108,10 @@ <combo_item name="Unconstrained" value="Unconstrained"> Unconstrained </combo_item> - <combo_item name="1:1" value="1:1" tool_tip="Group Insignia or 1st Life Profile"> + <combo_item name="1:1" value="1:1" tool_tip="Group insignia or 1st Life profile"> 1:1 </combo_item> - <combo_item name="4:3" value="4:3" tool_tip="2nd Life Profile"> + <combo_item name="4:3" value="4:3" tool_tip="2nd Life profile"> 4:3 </combo_item> <combo_item name="10:7" value="10:7" tool_tip="Classifieds and search listings, landmarks"> @@ -123,7 +123,7 @@ <combo_item name="16:10" value="16:10"> 16:10 </combo_item> - <combo_item name="16:9" value="16:9" tool_tip="Profile Picks"> + <combo_item name="16:9" value="16:9" tool_tip="Profile picks"> 16:9 </combo_item> <combo_item name="2:1" value="2:1"> diff --git a/indra/newview/skins/default/xui/en/floater_search.xml b/indra/newview/skins/default/xui/en/floater_search.xml new file mode 100644 index 0000000000..4ac0edca5a --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_search.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + can_resize="true" + height="400" + layout="topleft" + min_height="140" + min_width="467" + name="floater_search" + help_topic="floater_search" + save_rect="true" + single_instance="true" + title="Search [SECOND_LIFE]" + width="620"> + <floater.string + name="search_url"> + http://eniac21.lindenlab.com:10001/viewer/search/ + </floater.string> + <floater.string + name="loading_text"> + Loading... + </floater.string> + <floater.string + name="done_text"> + Done + </floater.string> + <layout_stack + bottom="400" + follows="left|right|top|bottom" + layout="topleft" + left="10" + name="stack1" + top="20" + width="600"> + <layout_panel + height="12" + layout="topleft" + left_delta="0" + name="external_controls" + top_delta="0" + user_resize="false" + width="570"> + <web_browser + bottom="-10" + follows="left|right|top|bottom" + layout="topleft" + left="0" + name="browser" + top="0" + width="570" /> + <text + follows="bottom|left" + height="16" + layout="topleft" + left_delta="0" + name="status_text" + top_pad="4" + width="150" /> + </layout_panel> + </layout_stack> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml index bd1484c0fe..551f570b52 100644 --- a/indra/newview/skins/default/xui/en/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml @@ -125,7 +125,7 @@ layout="topleft" left="10" name="more_btn" - tool_tip="Advanced Options" + tool_tip="Advanced options" top="270" width="80" /> <button @@ -136,7 +136,7 @@ layout="topleft" left_delta="0" name="less_btn" - tool_tip="Advanced Options" + tool_tip="Advanced options" top_delta="0" width="80" /> <text diff --git a/indra/newview/skins/default/xui/en/floater_test_inspectors.xml b/indra/newview/skins/default/xui/en/floater_test_inspectors.xml index 2011f57d8b..126bca2074 100644 --- a/indra/newview/skins/default/xui/en/floater_test_inspectors.xml +++ b/indra/newview/skins/default/xui/en/floater_test_inspectors.xml @@ -93,7 +93,9 @@ top_pad="10" left_delta="0" height="20" - width="100"/> + width="100" + commit_callback.function="ShowGroupInspector" + commit_callback.parameter="" /> <button name="place_btn" label="Place" @@ -112,13 +114,35 @@ follows="left|top" font="SansSerif" height="20" - layout="topleft" left="0" max_length="65536" name="slurl" top_pad="4" - width="100"> + width="150"> secondlife:///app/agent/00000000-0000-0000-0000-000000000000/inspect </text> + <text + follows="left|top" + font="SansSerif" + height="20" + left="0" + max_length="65536" + name="slurl_group" + top_pad="4" + width="150"> + secondlife:///app/group/00000000-0000-0000-0000-000000000000/inspect + </text> + + <text + follows="left|top" + font="SansSerif" + height="20" + left="0" + max_length="65536" + name="slurl_group_about" + top_pad="4" + width="150"> + secondlife:///app/group/00000000-0000-0000-0000-000000000000/about + </text> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index d3ceb67ceb..b898fd7c93 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -87,7 +87,7 @@ image_selected="Tool_Grab" image_unselected="Tool_Grab" layout="topleft" - left_pad="8" + left_pad="20" name="button move" picture_style="true" tool_tip="Move" @@ -104,7 +104,7 @@ image_selected="Tool_Face" image_unselected="Tool_Face" layout="topleft" - left_pad="8" + left_pad="20" name="button edit" picture_style="true" tool_tip="Edit" @@ -121,7 +121,7 @@ image_selected="Tool_Create" image_unselected="Tool_Create" layout="topleft" - left_pad="8" + left_pad="20" name="button create" picture_style="true" tool_tip="Create" @@ -138,7 +138,7 @@ image_selected="Tool_Dozer" image_unselected="Tool_Dozer" layout="topleft" - left_pad="8" + left_pad="20" name="button land" picture_style="true" tool_tip="Land" @@ -207,71 +207,71 @@ layout="topleft" name="move_radio_group"> <radio_item - top_pad="6" + top_pad="6" label="Move" layout="topleft" name="radio move" /> <radio_item - top_pad="6" + top_pad="6" label="Lift (Ctrl)" layout="topleft" name="radio lift" /> <radio_item - top_pad="6" + top_pad="6" label="Spin (Ctrl+Shift)" layout="topleft" name="radio spin" /> <radio_group.commit_callback - function="BuildTool.commitRadioMove"/> - </radio_group> - <radio_group + function="BuildTool.commitRadioMove"/> + </radio_group> + <radio_group follows="left|top" - left="10" - top="54" - height="70" + left="10" + top="54" + height="70" layout="topleft" - name="edit_radio_group"> + name="edit_radio_group"> <radio_item - label="Move" - layout="topleft" - name="radio position" /> + label="Move" + layout="topleft" + name="radio position" /> <radio_item - top_pad="6" + top_pad="6" label="Rotate (Ctrl)" layout="topleft" name="radio rotate" /> <radio_item - top_pad="6" + top_pad="6" label="Stretch (Ctrl+Shift)" layout="topleft" name="radio stretch" /> <radio_item - top_pad="6" + top_pad="6" label="Select Texture" layout="topleft" name="radio select face" /> - <radio_group.commit_callback - function="BuildTool.commitRadioEdit"/> + <radio_group.commit_callback + function="BuildTool.commitRadioEdit"/> </radio_group> <check_box left="10" follows="left|top" height="16" - control_name="EditLinkedParts" + control_name="EditLinkedParts" label="Edit linked" layout="topleft" name="checkbox edit linked parts" > <check_box.commit_callback - function="BuildTool.selectComponent"/> + function="BuildTool.selectComponent"/> </check_box> - <check_box + <check_box control_name="ScaleUniform" height="19" label="Stretch Both Sides" layout="topleft" left="143" name="checkbox uniform" - top="50" + top="50" width="134" /> <check_box control_name="ScaleStretchTextures" @@ -292,10 +292,9 @@ name="checkbox snap to grid" width="134" /> <combo_box - height="20" + height="19" layout="topleft" follows="left|top" - top_pad="4" name="combobox grid mode" width="108"> <combo_box.item @@ -313,9 +312,8 @@ <combo_box.commit_callback function="BuildTool.gridMode"/> </combo_box> - <button + <button left_pad="0" - right="-12" image_disabled="ForwardArrow_Disabled" image_selected="ForwardArrow_Press" image_unselected="ForwardArrow_Off" @@ -323,10 +321,11 @@ label_selected="Options" layout="topleft" name="Options..." - tool_tip="Grid Options" + tool_tip="Grid options" top_delta="0" + right="-10" width="18" - height="18" > + height="19" > <button.commit_callback function="BuildTool.gridOptions"/> </button> @@ -362,8 +361,8 @@ follows="left|top" height="20" image_disabled="Object_Pyramid" - image_disabled_selected="object_pyramid_active.tga" - image_selected="object_pyramid_active.tga" + image_disabled_selected="Object_Pyramid" + image_selected="Object_Pyramid" image_unselected="Object_Pyramid" layout="topleft" left_delta="26" @@ -376,8 +375,8 @@ follows="left|top" height="20" image_disabled="Object_Tetrahedron" - image_disabled_selected="object_tetrahedron_active.tga" - image_selected="object_tetrahedron_active.tga" + image_disabled_selected="Object_Tetrahedron" + image_selected="Object_Tetrahedron" image_unselected="Object_Tetrahedron" layout="topleft" left_delta="26" @@ -715,7 +714,7 @@ layout="topleft" left="135" name="button apply to selection" - tool_tip="Modify Selected Land" + tool_tip="Modify selected land" width="78"> <button.commit_callback function="BuildTool.applyToSelection"/> @@ -727,9 +726,9 @@ follows="left|top" halign="right" layout="topleft" - right="-13" + right="-10" name="obj_count" - top_pad="8" + top_pad="6" width="143"> Objects: [COUNT] </text> @@ -739,7 +738,7 @@ follows="left|top" halign="right" layout="topleft" - right="-13" + right="-10" name="prim_count" width="143"> Prims: [COUNT] @@ -747,31 +746,32 @@ <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" + tab_height="25" + top="170" width="280"> - <panel - border="false" - follows="left|top|right|bottom" - label="General" - layout="topleft" - mouse_opaque="false" - help_topic="toolbox_general_tab" - name="General" - top="16"> - <panel.string - name="text deed continued"> - Deed - </panel.string> - <panel.string - name="text deed"> - Deed - </panel.string> + <panel + border="false" + follows="all" + label="General" + layout="topleft" + mouse_opaque="false" + help_topic="toolbox_general_tab" + name="General" + top="16" + width="280"> + <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 @@ -867,7 +867,6 @@ width="90"> Creator: </text> -<!-- TODO: add person inspector to creator name --> <text type="string" length="1" @@ -890,7 +889,6 @@ width="90"> Owner: </text> -<!--TODO: add person inspector to owner name--> <text type="string" length="1" @@ -910,31 +908,31 @@ left="10" height="18" name="Group:" - top_pad="5" + top_pad="4" width="75"> Group: </text> - <button - follows="top|left" - height="10" - image_disabled="Activate_Checkmark" - image_selected="Activate_Checkmark" - image_unselected="Activate_Checkmark" - image_color="White_50" - layout="topleft" - left_pad="0" - top_delta="2" - name="button set group" - picture_style="true" - tab_stop="false" - tool_tip="Choose a group to share this object's permissions" - width="10" /> + <button + follows="top|left" + height="10" + image_disabled="Activate_Checkmark" + image_selected="Activate_Checkmark" + image_unselected="Activate_Checkmark" + image_color="White_50" + layout="topleft" + left_pad="0" + top_delta="0" + name="button set group" + picture_style="true" + tab_stop="false" + tool_tip="Choose a group to share this object's permissions" + width="10" /> <name_box follows="left|top" height="18" initial_value="Loading..." layout="topleft" - left_pad="4" + left_pad="5" top_delta="-1" name="Group Name Proxy" width="150" /> @@ -947,9 +945,9 @@ layout="topleft" name="button deed" top_pad="0" - left="83" - tool_tip="Deeding gives this item away with Next Owner permissions. Group shared objects can be deeded by a group officer." - width="100" /> + left="100" + tool_tip="Deeding gives this item away with next owner permissions. Group shared objects can be deeded by a group officer." + width="80" /> <check_box height="19" follows="left|top" @@ -968,7 +966,7 @@ top_pad="15" left="10" name="label click action" - width="100"> + width="90"> Click to: </text> <combo_box @@ -976,7 +974,7 @@ height="20" layout="topleft" name="clickaction" - width="158" + width="168" left_pad="0"> <combo_box.item label="Touch (default)" @@ -1006,7 +1004,7 @@ layout="topleft" name="checkbox for sale" left="10" - width="100" /> + width="90" /> <!-- NEW SALE TYPE COMBO BOX --> <combo_box left_pad="0" @@ -1042,38 +1040,37 @@ control_name="Edit Cost" name="Edit Cost" label="Price: L$" - label_width="70" - width="168" + label_width="65" + width="150" min_val="1" height="20" max_val="999999999" /> <check_box - height="15" - width="100" - top_pad="3" - label="Show in search" - layout="topleft" - left="100" - name="search_check" - tool_tip="Let people see this object in search results" - /> -<panel + height="15" + width="110" + top_pad="3" + label="Show in search" + layout="topleft" + left="100" + name="search_check" + tool_tip="Let people see this object in search results" /> + <panel border="false" follows="left|top" layout="topleft" mouse_opaque="false" background_visible="true" - bg_alpha_color="FloaterUnfocusBorderColor" + bg_alpha_color="DkGray" name="perms_build" left="0" - top="240" + top="241" height="120" - width="280"> + width="278"> <text type="string" length="1" left="10" - top_pad="10" + top_pad="9" text_color="EmphasisColor" height="16" follows="left|top|right" @@ -1087,7 +1084,6 @@ follows="left|top" name="Anyone can:" width="250" - top_pad="5" left="10"> Anyone: </text> @@ -1216,7 +1212,7 @@ </panel> <panel border="false" - follows="left|top|right|bottom" + follows="all" height="367" label="Object" layout="topleft" @@ -1248,7 +1244,7 @@ label="Temporary" layout="topleft" name="Temporary Checkbox Ctrl" - tool_tip="Causes object to be deleted 1 minute after creation." + tool_tip="Causes object to be deleted 1 minute after creation" top_pad="0" width="123" /> <check_box @@ -1380,7 +1376,7 @@ layout="topleft" left_delta="0" name="label rotation" - top_pad="6" + top_pad="10" width="121"> Rotation (degrees) </text> @@ -1449,7 +1445,7 @@ height="19" layout="topleft" name="comboBaseType" - top="5" + top="6" left="125" width="150"> <combo_box.item @@ -1489,7 +1485,7 @@ height="19" layout="topleft" name="material" - top_pad="0" + top_pad="5" width="150"> <combo_box.item label="Stone" @@ -1528,7 +1524,7 @@ layout="topleft" left_delta="0" name="text cut" - top_pad="6" + top_pad="5" width="150"> Path Cut (begin/end) </text> @@ -1610,7 +1606,7 @@ type="string" length="1" follows="left|top" - height="10" + height="15" layout="topleft" left="125" name="Hollow Shape" @@ -1623,7 +1619,7 @@ layout="topleft" left_delta="0" name="hole" - top_pad="4" + top_pad="3" width="150"> <combo_box.item label="Default" @@ -1650,7 +1646,7 @@ layout="topleft" left_delta="0" name="text twist" - top_pad="8" + top_pad="5" width="150"> Twist (begin/end) </text> @@ -1692,7 +1688,7 @@ layout="topleft" left="125" name="scale_taper" - top_pad="6" + top_pad="3" width="150"> Taper </text> @@ -1945,7 +1941,7 @@ layout="topleft" left_delta="0" name="sculpt mirror control" - tool_tip="Flips sculpted prim along the X axis." + tool_tip="Flips sculpted prim along the X axis" top_pad="8" visible="false" width="130" /> @@ -1955,7 +1951,7 @@ layout="topleft" left_delta="0" name="sculpt invert control" - tool_tip="Inverts the sculpted prims normals, making it appear inside-out." + tool_tip="Inverts the sculpted prims normals, making it appear inside-out" top_pad="4" visible="false" width="121" /> @@ -2005,7 +2001,7 @@ <panel border="false" - follows="left|top|right|bottom" + follows="all" height="367" label="Features" layout="topleft" @@ -2045,7 +2041,7 @@ layout="topleft" left="10" name="Flexible1D Checkbox Ctrl" - tool_tip="Allows object to flex about the Z axis. (Client-side only)" + tool_tip="Allows object to flex about the Z axis (Client-side only)" top_pad="10" width="121" /> <spinner @@ -2177,7 +2173,7 @@ left_pad="10" top_pad="-17" name="colorswatch" - tool_tip="Click to open Color Picker" + tool_tip="Click to open color picker" width="40" /> <texture_picker allow_no_texture="true" @@ -2243,7 +2239,7 @@ </panel> <panel border="false" - follows="left|top|right|bottom" + follows="all" height="367" label="Texture" layout="topleft" @@ -2280,9 +2276,9 @@ height="80" label="Color" layout="topleft" - left_pad="25" + left_pad="15" name="colorswatch" - tool_tip="Click to open Color Picker" + tool_tip="Click to open color picker" top_delta="0" width="64" /> <text @@ -2291,10 +2287,10 @@ follows="left|top" height="10" layout="topleft" - left_pad="20" + left_pad="15" name="color trans" top="6" - width="100"> + width="110"> Transparency % </text> <spinner @@ -2357,7 +2353,7 @@ left_delta="0" name="combobox texgen" top_pad="4" - width="87"> + width="60"> <combo_box.item label="Default" name="Default" @@ -2376,7 +2372,7 @@ name="label shininess" left_pad="5" top_pad="-36" - width="80"> + width="60"> Shininess </text> <combo_box @@ -2385,7 +2381,7 @@ left_delta="0" name="combobox shininess" top_pad="4" - width="80"> + width="60"> <combo_box.item label="None" name="None" @@ -2539,7 +2535,7 @@ name="tex scale" top_pad="5" width="200"> - Repeats per Face + Repeats / Face </text> <spinner follows="left|top" @@ -2588,9 +2584,9 @@ height="19" increment="1" initial_value="0" - label="Rotation (degrees)" + label="Rotation˚" layout="topleft" - label_width="100" + label_width="100" left="10" max_val="9999" min_val="-9999" @@ -2603,7 +2599,7 @@ follows="left|top" height="19" initial_value="1" - label="Repeats Per Meter" + label="Repeats / Meter" layout="topleft" label_width="100" left="10" @@ -2615,7 +2611,7 @@ <button follows="left|top" font="SansSerifSmall" - height="18" + height="19" label="Apply" label_selected="Apply" layout="topleft" @@ -2644,7 +2640,7 @@ left="20" min_val="-1" name="TexOffsetU" - top_pad="5" + top_pad="6" width="160" /> <spinner follows="left|top" @@ -2658,99 +2654,104 @@ name="TexOffsetV" top_pad="1" width="160" /> + <panel + border="false" + follows="left|top" + layout="topleft" + mouse_opaque="false" + background_visible="true" + bg_alpha_color="DkGray" + name="Add_Media" + left="0" + top_pad="0" + height="75" + width="278"> <text type="string" length="1" follows="left|top" - height="19" + height="12" layout="topleft" left="10" - name="textbox autofix" - top_pad="4" - 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="122" - name="button align" - top_pad="-19" - width="68" /> - <text - type="string" - length="1" - follows="left|top" - height="12" - layout="topleft" - left="10" - top_pad="0" - name="media_tex" - width="100"> - Media: + top_pad="5" + name="media_tex" + width="260"> + Media URL </text> <line_editor - follows="left|top|right" - height="18" - layout="topleft" - left="20" + follows="left|top|right" + height="18" + layout="topleft" + left="10" read_only="true" - name="media_info" - select_on_focus="true" - top_delta="12" - width="230" /> - <button - follows="left|top" - font="SansSerifSmall" - height="13" - width="13" - image_unselected="add_btn.tga" - label="" - layout="topleft" - left="20" - name="add_media" - top_pad="3"> + name="media_info" + select_on_focus="true" + width="180" /> + <button + follows="top|left" + height="18" + image_selected="AddItem_Press" + image_unselected="AddItem_Off" + image_disabled="AddItem_Disabled" + layout="topleft" + left_pad="0" + name="add_media" + picture_style="true" + tab_stop="false" + top_delta="0" + tool_tip="Add Media" + width="18"> <button.commit_callback function="BuildTool.AddMedia"/> </button> <button - follows="left|top" - font="SansSerifSmall" - height="13" - width="13" - image_unselected="del_btn.tga" - label="" - layout="topleft" - left_pad="10" - name="delete_media" - top_delta="0" - left_delta="10" > + follows="top|left" + height="18" + image_selected="TrashItem_Press" + image_unselected="TrashItem_Off" + layout="topleft" + left_pad="5" + name="delete_media" + picture_style="true" + tool_tip="Delete this media texture" + top_delta="0" + width="18"> <button.commit_callback function="BuildTool.DeleteMedia"/> </button> - <button - follows="left|top" - font="SansSerifSmall" - height="15" - width="15" - image_unselected="gear.tga" - label="" - layout="topleft" + <button + follows="top|left" + tool_tip="Edit this Media" + height="18" + image_disabled="OptionsMenu_Disabled" + image_selected="OptionsMenu_Press" + image_unselected="OptionsMenu_Off" + layout="topleft" + left_pad="10" name="edit_media" - top_delta="0" - left_delta="190"> + picture_style="true" + top_delta="0" + width="18"> <button.commit_callback function="BuildTool.EditMedia"/> </button> - </panel> + + <button + follows="left|top" + font="SansSerifSmall" + height="19" + label="Align" + label_selected="Align Media" + layout="topleft" + left="10" + name="button align" + top_pad="5" + width="100" /> + </panel> + </panel> <panel border="false" - follows="left|top|right|bottom" + follows="all" label="Content" layout="topleft" left_delta="0" @@ -2761,7 +2762,7 @@ width="280"> <button follows="left|top" - height="22" + height="19" label="New Script" label_selected="New Script" layout="topleft" @@ -2771,7 +2772,7 @@ width="120" /> <button follows="left|top" - height="22" + height="19" label="Permissions" layout="topleft" left_pad="8" @@ -2785,10 +2786,10 @@ name="contents_inventory" top="50" width="260" /> - </panel> + </panel> </tab_container> - <panel - follows="left|top" + <panel + follows="left|top" height="384" layout="topleft" left_delta="0" diff --git a/indra/newview/skins/default/xui/en/floater_water.xml b/indra/newview/skins/default/xui/en/floater_water.xml index 6206ea29c2..a860b1038c 100644 --- a/indra/newview/skins/default/xui/en/floater_water.xml +++ b/indra/newview/skins/default/xui/en/floater_water.xml @@ -111,7 +111,7 @@ layout="topleft" left="40" name="WaterFogColor" - tool_tip="Click to open Color Picker" + tool_tip="Click to open color picker" top="30" width="40" /> <text diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml index 8f88366842..f37c0e9022 100644 --- a/indra/newview/skins/default/xui/en/floater_world_map.xml +++ b/indra/newview/skins/default/xui/en/floater_world_map.xml @@ -325,7 +325,7 @@ left_pad="4" max_chars="60" name="friend combo" - tool_tip="Friend to Show on Map" + tool_tip="Friend to show on map" top_delta="-4" width="202"> <combo_box.item @@ -355,7 +355,7 @@ left_pad="4" max_chars="64" name="landmark combo" - tool_tip="Landmark to Show on Map" + tool_tip="Landmark to show on map" top_delta="-4" width="202"> <combo_box.item diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml index a934e541da..5bf481e9cb 100644 --- a/indra/newview/skins/default/xui/en/inspect_avatar.xml +++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml @@ -86,7 +86,7 @@ min_val="0.05" name="volume_slider" show_text="false" - tool_tip="Voice Volume" + tool_tip="Voice volume" top_pad="0" value="0.5" width="150" /> diff --git a/indra/newview/skins/default/xui/en/inspect_group.xml b/indra/newview/skins/default/xui/en/inspect_group.xml new file mode 100644 index 0000000000..d3f599cbbf --- /dev/null +++ b/indra/newview/skins/default/xui/en/inspect_group.xml @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<!-- + Not can_close / no title to avoid window chrome + Single instance - only have one at a time, recycle it each spawn +--> +<floater + bevel_style="in" + bg_opaque_color="MouseGray" + can_close="false" + can_minimize="false" + height="138" + layout="topleft" + name="inspect_group" + single_instance="true" + sound_flags="0" + visible="true" + width="245"> + <string name="PrivateGroup">Private group</string> + <string name="FreeToJoin">Free to join</string> + <string name="CostToJoin">L$[AMOUNT] to join</string> + <string name="YouAreMember">You are a member</string> + <text + follows="all" + font="SansSerifLargeBold" + height="18" + left="8" + name="group_name" + top="5" + text_color="white" + use_ellipses="true" + width="240" + word_wrap="false"> + Grumpity's Grumpy Group of Moose + </text> + <text + follows="all" + font="SansSerifSmallBold" + text_color="White" + height="18" + left="8" + name="group_subtitle" + use_ellipses="true" + top_pad="0" + width="170"> + 123 members + </text> + <text + follows="all" + height="50" + left="8" + name="group_details" + top_pad="0" + width="170" + word_wrap="true"> +A group of folks charged with creating a room with a moose. +Fear the moose! Fear it! And the mongoose too! + </text> + <text + follows="all" + height="15" + left="8" + name="group_cost" + top_pad="2" + width="170"> +L$123 to join + </text> + <icon + follows="all" + height="38" + right="-25" + mouse_opaque="true" + name="group_icon" + top="24" + width="38" /> + <button + follows="top|left" + height="18" + image_disabled="ForwardArrow_Disabled" + image_selected="ForwardArrow_Press" + image_unselected="ForwardArrow_Off" + name="view_profile_btn" + picture_style="true" + right="-8" + top="35" + left_delta="110" + tab_stop="false" + width="18" /> + <button + follows="bottom|left" + height="23" + label="Join" + left="8" + top="246" + name="join_btn" + width="100" + commit_callback.function="InspectGroup.Join"/> + <button + follows="bottom|left" + height="23" + label="Leave" + left="8" + top="246" + name="leave_btn" + width="100" + commit_callback.function="InspectGroup.Leave"/> +</floater> diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index 72cbd3bcd5..62940b87dc 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -457,14 +457,6 @@ function="Inventory.DoToSelected" parameter="replaceoutfit" /> </menu_item_call> - <menu_item_call - label="Wear As Ensemble" - layout="topleft" - name="Wear As Ensemble"> - <menu_item_call.on_click - function="Inventory.DoToSelected" - parameter="wearasensemble" /> - </menu_item_call> <menu_item_separator layout="topleft" /> <menu_item_call @@ -486,11 +478,12 @@ parameter="open" /> </menu_item_call> <menu_item_separator - layout="topleft" /> + layout="topleft" + name="Landmark Separator" /> <menu_item_call label="About Landmark" layout="topleft" - name="Teleport To Landmark"> + name="About Landmark"> <menu_item_call.on_click function="Inventory.DoToSelected" parameter="about" /> diff --git a/indra/newview/skins/default/xui/en/menu_landmark.xml b/indra/newview/skins/default/xui/en/menu_landmark.xml index 64fec3ab40..54a4095967 100644 --- a/indra/newview/skins/default/xui/en/menu_landmark.xml +++ b/indra/newview/skins/default/xui/en/menu_landmark.xml @@ -29,4 +29,12 @@ function="Places.OverflowMenu.Action" parameter="pick" /> </menu_item_call> + <menu_item_call + label="Add to Favorites Bar" + layout="topleft" + name="add_to_favbar"> + <menu_item_call.on_click + function="Places.OverflowMenu.Action" + parameter="add_to_favbar" /> + </menu_item_call> </toggleable_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 index 3c7b6dad14..cc17e9dd4b 100644 --- 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 @@ -2,12 +2,26 @@ <menu name="menu_group_plus" left="0" bottom="0" visible="false" mouse_opaque="false" opaque="true" color="MenuDefaultBgColor" drop_shadow="false"> - <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_check + label="Sort by Name" + name="sort_name"> + <menu_item_check.on_click + function="People.Friends.ViewSort.Action" + parameter="sort_name" /> + <menu_item_check.on_check + function="People.Friends.ViewSort.CheckItem" + parameter="sort_name" /> + </menu_item_check> + <menu_item_check + label="Sort by Status" + name="sort_status"> + <menu_item_check.on_click + function="People.Friends.ViewSort.Action" + parameter="sort_status" /> + <menu_item_check.on_check + function="People.Friends.ViewSort.CheckItem" + parameter="sort_status" /> + </menu_item_check> <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" /> 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 index ed03cd467c..d09871cff3 100644 --- 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 @@ -2,12 +2,26 @@ <menu name="menu_group_plus" left="0" bottom="0" visible="false" mouse_opaque="false" opaque="true" color="MenuDefaultBgColor" drop_shadow="false"> - <menu_item_call name="sort_most" label="Sort by Most Recent"> - <menu_item_call.on_click function="People.Recent.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.Recent.ViewSort.Action" userdata="sort_name" /> - </menu_item_call> + <menu_item_check + label="Sort by Most Recent" + name="sort_most"> + <menu_item_check.on_click + function="People.Recent.ViewSort.Action" + parameter="sort_recent" /> + <menu_item_check.on_check + function="People.Recent.ViewSort.CheckItem" + parameter="sort_recent" /> + </menu_item_check> + <menu_item_check + label="Sort by Name" + name="sort_name"> + <menu_item_check.on_click + function="People.Recent.ViewSort.Action" + parameter="sort_name" /> + <menu_item_check.on_check + function="People.Recent.ViewSort.CheckItem" + parameter="sort_name" /> + </menu_item_check> <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" /> diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml new file mode 100644 index 0000000000..c95cf32a5a --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml @@ -0,0 +1,118 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<menu + bottom="806" + layout="topleft" + left="0" + mouse_opaque="false" + name="menu_folder_gear" + visible="false"> + <menu_item_call + label="Add Landmark" + layout="topleft" + name="add_landmark"> + <on_click + function="Places.LandmarksGear.Add.Action" + parameter="add_landmark" /> + </menu_item_call> + <menu_item_call + label="Add Folder" + layout="topleft" + name="add_folder"> + <on_click + function="Places.LandmarksGear.Add.Action" + parameter="category" /> + <on_enable + function="Places.LandmarksGear.Enable" + parameter="category" /> + </menu_item_call> + <menu_item_separator + layout="topleft" /> + <menu_item_call + label="Cut" + layout="topleft" + name="cut"> + <on_click + function="Places.LandmarksGear.CopyPaste.Action" + parameter="cut" /> + </menu_item_call> + <menu_item_call + label="Copy" + layout="topleft" + name="copy_folder"> + <on_click + function="Places.LandmarksGear.CopyPaste.Action" + parameter="copy" /> + </menu_item_call> + <menu_item_call + label="Paste" + layout="topleft" + name="paste"> + <on_click + function="Places.LandmarksGear.CopyPaste.Action" + parameter="paste" /> + <on_enable + function="Places.LandmarksGear.Enable" + parameter="paste" /> + </menu_item_call> + <menu_item_call + label="Rename" + layout="topleft" + name="rename"> + <on_click + function="Places.LandmarksGear.CopyPaste.Action" + parameter="rename" /> + </menu_item_call> + <menu_item_call + label="Delete" + layout="topleft" + name="delete"> + <on_click + function="Places.LandmarksGear.CopyPaste.Action" + parameter="delete" /> + </menu_item_call> + <menu_item_separator + layout="topleft" /> + <menu_item_call + label="Expand" + layout="topleft" + name="expand"> + <on_click + function="Places.LandmarksGear.Folding.Action" + parameter="expand" /> + </menu_item_call> + <menu_item_call + label="Collapse" + layout="topleft" + name="collapse"> + <on_click + function="Places.LandmarksGear.Folding.Action" + parameter="collapse" /> + </menu_item_call> + <menu_item_call + label="Expand all folders" + layout="topleft" + name="expand_all"> + <on_click + function="Places.LandmarksGear.Folding.Action" + parameter="expand_all" /> + </menu_item_call> + <menu_item_call + label="Collapse all folders" + layout="topleft" + name="collapse_all"> + <on_click + function="Places.LandmarksGear.Folding.Action" + parameter="collapse_all" /> + </menu_item_call> + <menu_item_check + label="Sort by Date" + layout="topleft" + name="sort_by_date"> + <on_check + function="Places.LandmarksGear.Enable" + parameter="sort_by_date" /> + <on_click + function="Places.LandmarksGear.Folding.Action" + parameter="sort_by_date" /> + </menu_item_check> +</menu> diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml new file mode 100644 index 0000000000..0246d775ee --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml @@ -0,0 +1,150 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<menu + bottom="806" + layout="topleft" + left="0" + mouse_opaque="false" + name="menu_ladmark_gear" + visible="false"> + <menu_item_call + label="Teleport" + layout="topleft" + name="teleport"> + <on_click + function="Places.LandmarksGear.Custom.Action" + parameter="teleport" /> + <on_enable + function="Places.LandmarksGear.Enable" + parameter="teleport" /> + </menu_item_call> + <menu_item_call + label="More Information" + layout="topleft" + name="more_info"> + <on_click + function="Places.LandmarksGear.Custom.Action" + parameter="more_info" /> + <on_enable + function="Places.LandmarksGear.Enable" + parameter="more_info" /> + </menu_item_call> + <menu_item_call + label="Show on Map" + layout="topleft" + name="show_on_map"> + <on_click + function="Places.LandmarksGear.Custom.Action" + parameter="show_on_map" /> + </menu_item_call> + <menu_item_separator + layout="topleft" /> + <menu_item_call + label="Add Landmark" + layout="topleft" + name="add_landmark"> + <on_click + function="Places.LandmarksGear.Add.Action" + parameter="add_landmark" /> + </menu_item_call> + <menu_item_call + label="Add Folder" + layout="topleft" + name="add_folder"> + <on_click + function="Places.LandmarksGear.Add.Action" + parameter="category" /> + <on_enable + function="Places.LandmarksGear.Enable" + parameter="category" /> + </menu_item_call> + <menu_item_separator + layout="topleft" /> + <menu_item_call + label="Cut" + layout="topleft" + name="cut"> + <on_click + function="Places.LandmarksGear.CopyPaste.Action" + parameter="cut" /> + </menu_item_call> + <menu_item_call + label="Copy Landmark" + layout="topleft" + name="copy_landmark"> + <on_click + function="Places.LandmarksGear.CopyPaste.Action" + parameter="copy" /> + </menu_item_call> + <menu_item_call + label="Copy SLURL" + layout="topleft" + name="copy_slurl"> + <on_click + function="Places.LandmarksGear.CopyPaste.Action" + parameter="copy_slurl" /> + </menu_item_call> + <menu_item_call + label="Paste" + layout="topleft" + name="paste"> + <on_click + function="Places.LandmarksGear.CopyPaste.Action" + parameter="paste" /> + <on_enable + function="Places.LandmarksGear.Enable" + parameter="paste" /> + </menu_item_call> + <menu_item_call + label="Rename" + layout="topleft" + name="rename"> + <on_click + function="Places.LandmarksGear.CopyPaste.Action" + parameter="rename" /> + </menu_item_call> + <menu_item_call + label="Delete" + layout="topleft" + name="delete"> + <on_click + function="Places.LandmarksGear.CopyPaste.Action" + parameter="delete" /> + </menu_item_call> + <menu_item_separator + layout="topleft" /> + <menu_item_call + label="Expand all folders" + layout="topleft" + name="expand_all"> + <on_click + function="Places.LandmarksGear.Folding.Action" + parameter="expand_all" /> + </menu_item_call> + <menu_item_call + label="Collapse all folders" + layout="topleft" + name="collapse_all"> + <on_click + function="Places.LandmarksGear.Folding.Action" + parameter="collapse_all" /> + </menu_item_call> + <menu_item_check + label="Sort by Date" + layout="topleft" + name="sort_by_date"> + <on_check + function="Places.LandmarksGear.Enable" + parameter="sort_by_date" /> + <on_click + function="Places.LandmarksGear.Folding.Action" + parameter="sort_by_date" /> + </menu_item_check> + <menu_item_call + label="Create Pick" + layout="topleft" + name="create_pick"> + <on_click + function="Places.LandmarksGear.Custom.Action" + parameter="create_pick" /> + </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 index 98dd2ddd79..5979bfab4f 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -19,7 +19,7 @@ parameter="preferences" /> </menu_item_call> <menu_item_call - label="Manage My Account" + label="My Dashboard" layout="topleft" name="Manage My Account"> <menu_item_call.on_click @@ -272,6 +272,28 @@ name="Land" tear_off="true"> <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_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="Property Lines" layout="topleft" name="Property Lines" @@ -292,16 +314,6 @@ 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_item_separator layout="topleft" /> @@ -951,36 +963,6 @@ 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> <menu create_jump_keys="true" @@ -1229,6 +1211,17 @@ layout="topleft" name="Highlighting and Visibility" tear_off="true"> + <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="Hide Particles" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 9dcd94eb20..36a4798367 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -770,6 +770,14 @@ You can not wear clothes or body parts that are in the trash <notification icon="alertmodal.tga" + name="MaxAttachmentsOnOutfit" + type="alertmodal"> +Could not attach object. +Exceeds the attachments limit of [MAX_ATTACHMENTS] objects. Please detach another object first. + </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. @@ -6132,6 +6140,16 @@ Your L$ balance is shown in the upper-right. <notification icon="notify.tga" + name="BuyLindenDollarSuccess" + type="notify"> +Thank you for your payment! + +When processing completes, your L$ balance will be credited. If your payment takes more than 20 minutes to complete, the purchase amount will be credited to your account for use on your next purchase. + +Payment status can be checked on your Transaction History page at SecondLife.com. + </notification> + <notification + icon="notify.tga" name="FirstSit" type="notify"> You are sitting. 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 index f7f08b9b6a..69d90e4c7d 100644 --- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml @@ -38,12 +38,13 @@ width="20" /> <text follows="left|right" - font="SansSerifSmallBold" + font="SansSerifSmall" + font.style="BOLD" height="20" layout="topleft" left_pad="5" name="avatar_name" - text_color="white" + text_color="grey" top="4" use_ellipses="true" value="Unknown" diff --git a/indra/newview/skins/default/xui/en/panel_chat_header.xml b/indra/newview/skins/default/xui/en/panel_chat_header.xml new file mode 100644 index 0000000000..a9f622e018 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_chat_header.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + follows="left|top|right" + height="57" + label="im_header_container" + layout="topleft" + left="8" + name="im_header_container"> + <panel + background_visible="true" + bevel_style="in" + bg_alpha_color="black" + follows="left|top|right" + height="30" + label="im_header" + layout="topleft" + name="im_header" + top_pad="17"> + <avatar_icon + follows="left" + height="20" + image_name="icon_avatar_online.tga" + layout="topleft" + left="5" + mouse_opaque="true" + name="avatar_icon" + top="5" + width="20" /> + <text + follows="left|right" + font="SansSerifBigBold" + height="20" + layout="topleft" + left_pad="10" + right="-50" + name="user_name" + text_color="white" + top="5" + value="Darth Vader" + use_ellipses="true" /> + <text + follows="right" + font="SansSerifBig" + height="20" + layout="topleft" + name="time_box" + right="0" + text_color="white" + top="5" + value="23:30" + width="50" /> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_chat_separator.xml b/indra/newview/skins/default/xui/en/panel_chat_separator.xml new file mode 100644 index 0000000000..dd27595cdb --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_chat_separator.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + follows="left|right|top" + height="10" + layout="topleft" + left="8" + name="chat_separator_container"> + <panel + background_visible="true" + bg_alpha_color="black" + follows="left|right|top" + height="1" + layout="topleft" + name="chat_separator_panel" + top_pad="5" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_classified.xml b/indra/newview/skins/default/xui/en/panel_classified.xml index fde795260e..18d12aef70 100644 --- a/indra/newview/skins/default/xui/en/panel_classified.xml +++ b/indra/newview/skins/default/xui/en/panel_classified.xml @@ -40,7 +40,7 @@ layout="topleft" left_delta="0" name="given_name_editor" - tool_tip="Name must begin with a letter or number, not punctuation." + tool_tip="Name must begin with a letter or number, not punctuation" top_delta="288" width="400" /> <text_editor @@ -61,7 +61,7 @@ layout="topleft" left="20" name="location_editor" - tool_tip="Set the location for this classified to your current position." + tool_tip="Set the location for this classified to your current position" width="400" /> <button follows="left|top" diff --git a/indra/newview/skins/default/xui/en/panel_edit_alpha.xml b/indra/newview/skins/default/xui/en/panel_edit_alpha.xml new file mode 100644 index 0000000000..40647e1b81 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_edit_alpha.xml @@ -0,0 +1,126 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> + <panel + follows="all" + height="400" + layout="topleft" + left="10" + name="edit_alpha_panel" + top_pad="10" + width="313" > + <panel + border="true" + follows="left|top|right" + height="180" + left="10" + layout="topleft" + name="avatar_alpha_color_panel" + top="0" + width="293" > + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="80" + label="Lower Alpha" + layout="topleft" + left="10" + name="Lower Alpha" + tool_tip="Click to choose a picture" + top="10" + 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_pad="10" + name="Upper Alpha" + tool_tip="Click to choose a picture" + top="10" + 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_pad="10" + name="Head Alpha" + tool_tip="Click to choose a picture" + top="10" + 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="10" + name="Eye Alpha" + tool_tip="Click to choose a picture" + top="100" + 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_pad="10" + name="Hair Alpha" + tool_tip="Click to choose a picture" + top_delta="-4" + 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" /> + </panel> +</panel> + diff --git a/indra/newview/skins/default/xui/en/panel_edit_eyes.xml b/indra/newview/skins/default/xui/en/panel_edit_eyes.xml new file mode 100644 index 0000000000..9789da5796 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_edit_eyes.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> + <panel + follows="all" + height="400" + layout="topleft" + left="10" + name="edit_eyes_panel" + top_pad="10" + width="313" > + <panel + border="true" + follows="left|top|right" + height="100" + left="10" + layout="topleft" + name="avatar_eye_color_panel" + top="0" + width="293" > + <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_pad="10" + width="64" /> + </panel> + <accordion + follows="left|top|right|bottom" + height ="340" + left="10" + name="wearable_accordion" + top_pad="10" + width="303"> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="eyes_main_tab" + title="Eyes"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="eyes_main_param_list" + top="0" + width="303" /> + </accordion_tab> + </accordion> +</panel> + diff --git a/indra/newview/skins/default/xui/en/panel_edit_gloves.xml b/indra/newview/skins/default/xui/en/panel_edit_gloves.xml new file mode 100644 index 0000000000..517cdd75fb --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_edit_gloves.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> + <panel + follows="all" + height="400" + layout="topleft" + left="10" + name="edit_gloves_panel" + top_pad="10" + width="313" > + <panel + border="true" + follows="left|top|right" + height="100" + left="10" + layout="topleft" + name="avatar_gloves_color_panel" + top="0" + width="293" > + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="80" + label="Fabric" + layout="topleft" + left="10" + name="Fabric" + 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/Tint" + layout="topleft" + left_pad="10" + name="Color/Tint" + tool_tip="Click to open color picker" + top="10" + width="64" /> + </panel> + <accordion + follows="left|top|right|bottom" + height ="340" + left="10" + name="wearable_accordion" + top_pad="10" + width="303"> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="gloves_main_tab" + title="Gloves"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="gloves_main_param_list" + top="0" + width="303" /> + </accordion_tab> + </accordion> +</panel> + diff --git a/indra/newview/skins/default/xui/en/panel_edit_hair.xml b/indra/newview/skins/default/xui/en/panel_edit_hair.xml new file mode 100644 index 0000000000..d2ee2ebf2a --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_edit_hair.xml @@ -0,0 +1,97 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> + <panel + follows="all" + height="400" + layout="topleft" + left="10" + name="edit_hair_panel" + top_pad="10" + width="313" > + <panel + border="true" + follows="left|top|right" + height="100" + left="10" + layout="topleft" + name="avatar_hair_color_panel" + top="0" + width="293" > + <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="10" + width="64" /> + </panel> + <accordion + follows="left|top|right|bottom" + height ="340" + left="10" + name="wearable_accordion" + top_pad="10" + width="303"> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="hair_color_tab" + title="Color"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="hair_color_param_list" + top="0" + width="303" /> + </accordion_tab> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="hair_style_tab" + title="Style"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="hair_style_param_list" + top="0" + width="303" /> + </accordion_tab> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="hair_eyebrows_tab" + title="Eyebrows"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="hair_eyebrows_param_list" + top="0" + width="303" /> + </accordion_tab> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="hair_facial_tab" + title="Facial"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="hair_facial_param_list" + top="0" + width="303" /> + </accordion_tab> + </accordion> +</panel> + diff --git a/indra/newview/skins/default/xui/en/panel_edit_jacket.xml b/indra/newview/skins/default/xui/en/panel_edit_jacket.xml new file mode 100644 index 0000000000..0b54944e29 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_edit_jacket.xml @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> + <panel + follows="all" + height="400" + layout="topleft" + left="10" + name="edit_jacket_panel" + top_pad="10" + width="313" > + <panel + border="true" + follows="left|top|right" + height="100" + left="10" + layout="topleft" + name="avatar_jacket_color_panel" + top="0" + width="293" > + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="80" + label="Upper Fabric" + layout="topleft" + left="10" + name="Upper Fabric" + tool_tip="Click to choose a picture" + top="10" + width="64" /> + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="80" + label="Lower Fabric" + layout="topleft" + left_pad="10" + name="Lower Fabric" + 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/Tint" + layout="topleft" + left_pad="10" + name="Color/Tint" + tool_tip="Click to open color picker" + top="10" + width="64" /> + </panel> + <accordion + follows="left|top|right|bottom" + height ="340" + left="10" + name="wearable_accordion" + top_pad="10" + width="303"> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="jacket_main_tab" + title="Jacket"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="jacket_main_param_list" + top="0" + width="303" /> + </accordion_tab> + </accordion> +</panel> + diff --git a/indra/newview/skins/default/xui/en/panel_edit_pants.xml b/indra/newview/skins/default/xui/en/panel_edit_pants.xml new file mode 100644 index 0000000000..939314f9f9 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_edit_pants.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> + <panel + follows="all" + height="400" + layout="topleft" + left="10" + name="edit_pants_panel" + top_pad="10" + width="313" > + <panel + border="true" + follows="left|top|right" + height="100" + left="10" + layout="topleft" + name="avatar_pants_color_panel" + top="0" + width="293" > + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="80" + label="Fabric" + layout="topleft" + left="10" + name="Fabric" + 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/Tint" + layout="topleft" + left_pad="10" + name="Color/Tint" + tool_tip="Click to open color picker" + top="10" + width="64" /> + </panel> + <accordion + follows="left|top|right|bottom" + height ="340" + left="10" + name="wearable_accordion" + top_pad="10" + width="303"> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="pants_main_tab" + title="Pants"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="pants_main_param_list" + top="0" + width="303" /> + </accordion_tab> + </accordion> +</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 index 453e1319a6..bac6f6e4d1 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml @@ -2,73 +2,79 @@ <panel background_visible="true" bevel_style="in" + follows="left|top|right|bottom" height="570" label="Edit Pick" layout="topleft" left="0" + min_height="350" name="panel_edit_pick" top="0" width="333"> + <button + follows="top|right" + height="23" + image_overlay="BackArrow_Off" + layout="topleft" + name="back_btn" + picture_style="true" + left="10" + tab_stop="false" + top="2" + width="23" /> <text type="string" length="1" follows="top" - font="SansSerifHugeBold" + font="SansSerifHuge" height="15" layout="topleft" - left="10" + left_pad="10" name="title" text_color="white" top="5" width="250"> Edit Pick </text> - <button - follows="top|right" - height="20" - image_overlay="BackArrow_Off" - layout="topleft" - name="back_btn" - picture_style="true" - right="-20" - top="7" - width="20" /> <scroll_container color="DkGray2" - follows="left|top|right|bottom" - height="470" + follows="all" + height="510" layout="topleft" left="10" top_pad="10" name="profile_scroll" - reserve_scroll_corner="true" + reserve_scroll_corner="false" opaque="true" width="313"> <panel name="scroll_content_panel" - follows="left|top|right" + follows="left|top" + min_height="300" layout="topleft" top="0" + background_visible="false" + height="470" left="0" - width="298" - height="555"> + width="295"> <texture_picker follows="left|top|right" height="197" - width="280" + width="290" layout="topleft" top="20" left="10" name="pick_snapshot" /> - <icon - height="16" - image_name="image_edit_icon.tga" - layout="topleft" - name="edit_icon" - left="245" - top="35" - visible="true" - width="16" /> + <button + height="18" + image_overlay="AddItem_Off" + layout="topleft" + right="-5" + name="edit_icon" + label="" + tool_tip="Click to select an image" + top="27" + width="18" /> <text type="string" length="1" @@ -80,8 +86,9 @@ left="10" top="215" name="Name:" - text_color="white"> - Name: + text_color="white" + width="290"> + Title: </text> <line_editor follows="left|top|right" @@ -93,7 +100,7 @@ max_length="63" name="pick_name" text_color="black" - width="280" /> + width="290" /> <text type="string" length="1" @@ -105,13 +112,14 @@ left="10" top_pad="20" name="description_label" - text_color="white"> + text_color="white" + width="290"> Description: </text> <text_editor follows="left|top|right" height="100" - width="280" + width="290" hide_scrollbar="false" layout="topleft" left="10" @@ -131,7 +139,8 @@ left="10" name="location_label" text_color="white" - top_pad="20"> + top_pad="20" + width="290"> Location: </text> <text @@ -144,8 +153,7 @@ name="pick_location" right="-10" top_pad="2" - text_color="white" - width="280" + width="290" word_wrap="true"> loading... </text> @@ -154,22 +162,24 @@ height="20" label="Set to Current Location" layout="topleft" - left="10" + left="8" + top_pad="0" name="set_to_curr_location_btn" width="200" /> </panel> </scroll_container> <panel follows="left|right|bottom" - height="30" + height="20" label="bottom_panel" layout="topleft" left="10" name="bottom_panel" - top_pad="2"> + top_pad="5" + width="303"> <button follows="bottom|left" - height="25" + height="19" label="Save [WHAT]" layout="topleft" name="save_changes_btn" @@ -178,12 +188,12 @@ width="130" /> <button follows="bottom|left" - height="25" + height="19" label="Cancel" layout="topleft" name="cancel_btn" left_pad="5" - top_delta="0" + right="-1" width="130" /> </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 index 0202323dcf..d268258f6f 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_profile.xml @@ -1,20 +1,17 @@ <?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" + class="edit_profile_panel" + follows="all" + height="535" label="Profile Edit" layout="topleft" - left="10" - mouse_opaque="true" + left="0" name="edit_profile_panel" - top="10" - width="255"> + top="0" + width="313"> <string name="CaptionTextAcctInfo"> - [ACCTTYPE] + [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION] </string> <string @@ -51,192 +48,151 @@ <string name="no_partner_text" value="None" /> - <scroll_container + <scroll_container color="DkGray2" - follows="left|top|right|bottom" - height="300" + follows="all" + height="505" + min_height="300" layout="topleft" left="0" name="profile_scroll" reserve_scroll_corner="true" opaque="true" - width="255"> + top="0"> + <panel + name="scroll_content_panel" + follows="left|top|right" + layout="topleft" + top="0" + height="505" + min_height="300" + left="0" + width="313"> <panel - name="scroll_content_panel" + name="data_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="750" - layout="topleft" - left="0" - name="data_panel" - top_pad="10" - width="260"> + layout="topleft" + top="0" + height="505" + min_height="300" + left="0" + width="313"> <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" /> + follows="left|top|right" + height="244" + layout="topleft" + top="0" + left="0" + width="285"> + <panel + follows="left|top" + height="117" + layout="topleft" + left="10" + name="second_life_image_panel" + top="0" + width="285"> + <text + follows="left|top|right" + font.style="BOLD" + height="15" + layout="topleft" + left="0" + name="second_life_photo_title_text" + text_color="white" + value="[SECOND_LIFE]:" + width="170" /> + <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_pad="0" + width="102" /> </panel> - <icon - height="16" - image_name="image_edit_icon.tga" + <button + height="18" + image_overlay="AddItem_Off" layout="topleft" - left="75" name="2nd_life_edit_icon" - tool_tip="Click to select an image" - top="35" - width="16" /> + label="" + left="87" + tool_tip="Click to select an image" + top="25" + width="18" /> </panel> <text_editor type="string" length="1" follows="left|top|right" font="SansSerifSmall" - height="125" + height="100" layout="topleft" left="120" - top="30" - max_length="511" + top="18" name="sl_description_edit" - width="115" + width="173" 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" /> + follows="left|top" + height="117" + layout="topleft" + top_pad="5" + left="10" + name="first_life_image_panel" + width="285"> + <text + follows="left|top|right" + font.style="BOLD" + height="15" + layout="topleft" + left="0" + name="real_world_photo_title_text" + text_color="white" + value="Real World:" + width="173" /> + <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" + top_pad="0" + width="102" /> </panel> - <icon - height="16" - image_name="image_edit_icon.tga" + <button + height="18" + image_overlay="AddItem_Off" layout="topleft" - left="85" name="real_world_edit_icon" - tool_tip="Click to select an image" - top="210" - width="16" /> + label="" + left="87" + tool_tip="Click to select an image" + top="148" + width="18" /> <text_editor type="string" length="1" follows="left|top|right" font="SansSerifSmall" - height="125" + height="100" layout="topleft" left="120" - top="195" - max_length="254" + top="142" name="fl_description_edit" - width="115" + width="173" 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" @@ -247,8 +203,8 @@ left="10" name="title_homepage_text" text_color="white" - top_pad="20" - width="240"> + top_pad="10" + width="285"> Homepage: </text> <line_editor @@ -256,45 +212,45 @@ font="SansSerifSmall" height="20" layout="topleft" - left="9" + left="10" + top_pad="0" + value="http://" name="homepage_edit" - width="220"> - TODO + width="285"> </line_editor> <check_box follows="left|top" font="SansSerifSmall" - label="Show me in Search results" + label="Show me in Search results" layout="topleft" left="10" name="show_in_search_checkbox" - height="16" + height="15" text_enabled_color="white" - top_pad="20" - width="240"/> + top_pad="10" + width="240" /> <text follows="left|top" font="SansSerifSmall" - font.style="BOLD" + 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" /> + top_pad="5" + value="My Account:" + width="285" /> <text type="string" follows="left|top" font="SansSerifSmall" height="15" layout="topleft" - left_pad="10" + left="10" name="my_account_link" - top_delta="0" - value="Go to Dashboard" - width="100"/> + value="Go to My Dashboard" + width="285" /> <text follows="left|top|right" height="20" @@ -303,7 +259,7 @@ name="acc_status_text" top_pad="5" value="Resident. No payment info on file." - width="255" + width="285" word_wrap="true" /> <text follows="left|top" @@ -314,26 +270,26 @@ left="10" name="title_partner_text" text_color="white" - top_pad="15" - value="Partner:" - width="100" /> + top_pad="0" + value="My Partner:" + width="150" /> <text follows="left|top" height="15" + halign="right" layout="topleft" left_pad="10" + right="-10" name="partner_edit_link" - top_delta="0" value="[[URL] Edit]" - width="100" /> + width="150" /> <panel follows="left|top|right" height="15" layout="topleft" left="10" name="partner_data_panel" - top_pad="10" - width="255"> + width="285"> <text follows="left|top|right" height="30" @@ -342,7 +298,7 @@ name="partner_text" top="0" value="[FIRST] [LAST]" - width="240" + width="285" word_wrap="true" /> </panel> <text @@ -356,36 +312,36 @@ left="10" name="title_afk_text" text_color="white" - top_pad="15" - width="240"> + top_pad="0" + width="190"> Away Timeout: </text> <spinner control_name="AFKTimeout" decimal_digits="0" follows="left|top" - height="16" + halign="right" + height="15" 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" + left_pad="4" width="50" /> <text type="string" length="1" follows="left|top" - height="10" + halign="left" + height="15" layout="topleft" - left_pad="10" + left_pad="2" name="seconds_textbox" - top_delta="0" - width="128"> + width="70"> seconds </text> <text @@ -394,12 +350,12 @@ follows="left|top" height="10" layout="topleft" - font="SansSerifSmall" + font="SansSerifSmall" font.style="BOLD" - left="12" + text_color="white" + left="10" mouse_opaque="false" name="text_box3" - top_pad="25" width="240"> Busy Mode Response: </text> @@ -407,29 +363,27 @@ control_name="BusyModeResponse2" commit_on_focus_lost = "true" follows="left|top" - height="70" + height="56" layout="topleft" - left="12" + left="10" name="busy_response" - top_pad="10" - width="240" + width="285" word_wrap="true"> log_in_to_change - </text_editor> + </text_editor> </panel> </panel> </scroll_container> - <panel + <panel follows="bottom|left" - height="30" + height="20" left="10" name="profile_me_buttons_panel" - top_pad="10" - width="240"> + top_pad="5" + width="303"> <button follows="bottom|left" - font="SansSerifSmallBold" - height="25" + height="19" label="Save Changes" layout="topleft" left="0" @@ -438,16 +392,12 @@ width="130" /> <button follows="bottom|left" - font="SansSerifSmallBold" - height="25" + height="19" label="Cancel" layout="topleft" - left_pad="5" + left_pad="10" name="cancel_btn" - top_delta="0" + right="-1" width="130" /> </panel> </panel> - - - diff --git a/indra/newview/skins/default/xui/en/panel_edit_shape.xml b/indra/newview/skins/default/xui/en/panel_edit_shape.xml new file mode 100644 index 0000000000..a9dfcb82d6 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_edit_shape.xml @@ -0,0 +1,189 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> + <panel + follows="all" + height="400" + layout="topleft" + left="10" + name="edit_shape_panel" + top_pad="10" + width="313" > + <panel + border="true" + follows="top|left" + height="50" + left="10" + layout="topleft" + name="avatar_sex_panel" + top="10" + width="293" > + <text + follows="top|left" + height="16" + layout="topleft" + left="10" + name="gender_text" + width="303"> + Gender: + </text> + <radio_group + follows="all" + left="10" + height="34" + layout="topleft" + name="sex_radio" + top_pad="3" + width="200" > + <radio_item + follows="all" + height="16" + label="Female" + layout="topleft" + left="10" + name="radio" + width="82" /> + <radio_item + follows="all" + height="16" + label="Male" + layout="topleft" + left_pad="10" + name="radio2" + width="82" /> + </radio_group> + </panel> + <accordion + follows="left|top|right|bottom" + height ="330" + left="10" + name="wearable_accordion" + top_pad="10" + width="303"> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="shape_body_tab" + title="Body"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="shape_body_param_list" + top="0" + width="303" /> + </accordion_tab> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="shape_head_tab" + title="Head"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="shape_head_param_list" + top="0" + width="303" /> + </accordion_tab> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="shape_eyes_tab" + title="Eyes"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="shape_eyes_param_list" + top="0" + width="303" /> + </accordion_tab> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="shape_ears_tab" + title="Ears"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="shape_ears_param_list" + top="0" + width="303" /> + </accordion_tab> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="shape_nose_tab" + title="Nose"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="shape_nose_param_list" + top="0" + width="303" /> + </accordion_tab> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="shape_mouth_tab" + title="Mouth"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="shape_mouth_param_list" + top="0" + width="303" /> + </accordion_tab> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="shape_chin_tab" + title="Chin"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="shape_chin_param_list" + top="0" + width="303" /> + </accordion_tab> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="shape_torso_tab" + title="Torso"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="shape_torso_param_list" + top="0" + width="303" /> + </accordion_tab> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="shape_legs_tab" + title="Legs"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="shape_legs_param_list" + top="0" + width="303" /> + </accordion_tab> + </accordion> +</panel> + diff --git a/indra/newview/skins/default/xui/en/panel_edit_shirt.xml b/indra/newview/skins/default/xui/en/panel_edit_shirt.xml new file mode 100644 index 0000000000..258ee06697 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_edit_shirt.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> + <panel + follows="all" + height="400" + layout="topleft" + left="10" + name="edit_shirt_panel" + top_pad="10" + width="313" > + <panel + border="true" + follows="left|top|right" + height="100" + left="10" + layout="topleft" + name="avatar_shirt_color_panel" + top="0" + width="293" > + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="80" + label="Fabric" + layout="topleft" + left="10" + name="Fabric" + 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/Tint" + layout="topleft" + left_pad="10" + name="Color/Tint" + tool_tip="Click to open color picker" + top="10" + width="64" /> + </panel> + <accordion + follows="left|top|right|bottom" + height ="340" + left="10" + name="wearable_accordion" + top_pad="10" + width="303"> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="shirt_main_tab" + title="Shirt"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="shirt_main_param_list" + top="0" + width="303" /> + </accordion_tab> + </accordion> +</panel> + diff --git a/indra/newview/skins/default/xui/en/panel_edit_shoes.xml b/indra/newview/skins/default/xui/en/panel_edit_shoes.xml new file mode 100644 index 0000000000..22fced4aac --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_edit_shoes.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> + <panel + follows="all" + height="400" + layout="topleft" + left="10" + name="edit_shoes_panel" + top_pad="10" + width="313" > + <panel + border="true" + follows="left|top|right" + height="100" + left="10" + layout="topleft" + name="avatar_shoes_color_panel" + top="0" + width="293" > + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="80" + label="Fabric" + layout="topleft" + left="10" + name="Fabric" + 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/Tint" + layout="topleft" + left_pad="10" + name="Color/Tint" + tool_tip="Click to open color picker" + top="10" + width="64" /> + </panel> + <accordion + follows="left|top|right|bottom" + height ="340" + left="10" + name="wearable_accordion" + top_pad="10" + width="303"> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="shoes_main_tab" + title="Shoes"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="shoes_main_param_list" + top="0" + width="303" /> + </accordion_tab> + </accordion> +</panel> + diff --git a/indra/newview/skins/default/xui/en/panel_edit_skin.xml b/indra/newview/skins/default/xui/en/panel_edit_skin.xml new file mode 100644 index 0000000000..1a00277f43 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_edit_skin.xml @@ -0,0 +1,124 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> + <panel + follows="all" + height="400" + layout="topleft" + left="10" + name="edit_skin_panel" + top_pad="10" + width="313" > + <panel + border="true" + follows="left|top|right" + height="100" + left="10" + layout="topleft" + name="avatar_skin_color_panel" + top="0" + width="293" > + <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="10" + name="Head Tattoos" + tool_tip="Click to choose a picture" + top="10" + 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_pad="10" + name="Upper Tattoos" + tool_tip="Click to choose a picture" + top="10" + 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_pad="10" + name="Lower Tattoos" + tool_tip="Click to choose a picture" + top="10" + width="74" /> + </panel> + <accordion + follows="left|top|right|bottom" + height ="340" + left="10" + name="wearable_accordion" + top_pad="10" + width="303"> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="skin_color_tab" + title="Skin Color"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="skin_color_param_list" + top="0" + width="303" /> + </accordion_tab> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="skin_face_tab" + title="Face Detail"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="skin_face_param_list" + top="0" + width="303" /> + </accordion_tab> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="skin_makeup_tab" + title="Makeup"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="skin_makeup_param_list" + top="0" + width="303" /> + </accordion_tab> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="skin_body_tab" + title="Body Detail"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="skin_body_param_list" + top="0" + width="303" /> + </accordion_tab> + </accordion> +</panel> + diff --git a/indra/newview/skins/default/xui/en/panel_edit_skirt.xml b/indra/newview/skins/default/xui/en/panel_edit_skirt.xml new file mode 100644 index 0000000000..411d433604 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_edit_skirt.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> + <panel + follows="all" + height="400" + layout="topleft" + left="10" + name="edit_skirt_panel" + top_pad="10" + width="313" > + <panel + border="true" + follows="left|top|right" + height="100" + left="10" + layout="topleft" + name="avatar_skirt_color_panel" + top="0" + width="293" > + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="80" + label="Fabric" + layout="topleft" + left="10" + name="Fabric" + 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/Tint" + layout="topleft" + left_pad="10" + name="Color/Tint" + tool_tip="Click to open color picker" + top="10" + width="64" /> + </panel> + <accordion + follows="left|top|right|bottom" + height ="340" + left="10" + name="wearable_accordion" + top_pad="10" + width="303"> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="skirt_main_tab" + title="Skirt"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="skirt_main_param_list" + top="0" + width="303" /> + </accordion_tab> + </accordion> +</panel> + diff --git a/indra/newview/skins/default/xui/en/panel_edit_socks.xml b/indra/newview/skins/default/xui/en/panel_edit_socks.xml new file mode 100644 index 0000000000..faff67795c --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_edit_socks.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> + <panel + follows="all" + height="400" + layout="topleft" + left="10" + name="edit_socks_panel" + top_pad="10" + width="313" > + <panel + border="true" + follows="left|top|right" + height="100" + left="10" + layout="topleft" + name="avatar_socks_color_panel" + top="0" + width="293" > + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="80" + label="Fabric" + layout="topleft" + left="10" + name="Fabric" + 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/Tint" + layout="topleft" + left_pad="10" + name="Color/Tint" + tool_tip="Click to open color picker" + top="10" + width="64" /> + </panel> + <accordion + follows="left|top|right|bottom" + height ="340" + left="10" + name="wearable_accordion" + top_pad="10" + width="303"> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="socks_main_tab" + title="Socks"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="socks_main_param_list" + top="0" + width="303" /> + </accordion_tab> + </accordion> +</panel> + diff --git a/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml new file mode 100644 index 0000000000..b214cd3de0 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> + <panel + follows="all" + height="400" + layout="topleft" + left="10" + name="edit_tattoo_panel" + top_pad="10" + width="313" > + <panel + border="true" + follows="left|top|right" + height="100" + left="10" + layout="topleft" + name="avatar_tattoo_color_panel" + top="0" + width="293" > + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="80" + label="Head Tattoo" + layout="topleft" + left="10" + name="Head Tattoo" + tool_tip="Click to choose a picture" + top="10" + width="64" /> + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="80" + label="Upper Tattoo" + layout="topleft" + left_pad="10" + name="Upper Tattoo" + tool_tip="Click to choose a picture" + top="10" + width="64" /> + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="80" + label="Lower Tattoo" + layout="topleft" + left_pad="10" + name="Lower Tattoo" + tool_tip="Click to choose a picture" + top="10" + width="64" /> + </panel> +</panel> + diff --git a/indra/newview/skins/default/xui/en/panel_edit_underpants.xml b/indra/newview/skins/default/xui/en/panel_edit_underpants.xml new file mode 100644 index 0000000000..bb0b353a01 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_edit_underpants.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> + <panel + follows="all" + height="400" + layout="topleft" + left="10" + name="edit_underpants_panel" + top_pad="10" + width="313" > + <panel + border="true" + follows="left|top|right" + height="100" + left="10" + layout="topleft" + name="avatar_underpants_color_panel" + top="0" + width="293" > + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="80" + label="Fabric" + layout="topleft" + left="10" + name="Fabric" + 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/Tint" + layout="topleft" + left_pad="10" + name="Color/Tint" + tool_tip="Click to open color picker" + top="10" + width="64" /> + </panel> + <accordion + follows="left|top|right|bottom" + height ="340" + left="10" + name="wearable_accordion" + top_pad="10" + width="303"> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="underpants_main_tab" + title="Underpants"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="underpants_main_param_list" + top="0" + width="303" /> + </accordion_tab> + </accordion> +</panel> + diff --git a/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml new file mode 100644 index 0000000000..097cb14ee6 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> + <panel + follows="all" + height="400" + layout="topleft" + left="10" + name="edit_undershirt_panel" + top_pad="10" + width="313" > + <panel + border="true" + follows="left|top|right" + height="100" + left="10" + layout="topleft" + name="avatar_undershirt_color_panel" + top="0" + width="293" > + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="80" + label="Fabric" + layout="topleft" + left="10" + name="Fabric" + 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/Tint" + layout="topleft" + left_pad="10" + name="Color/Tint" + tool_tip="Click to open Color Picker" + top="10" + width="64" /> + </panel> + <accordion + follows="left|top|right|bottom" + height ="340" + left="10" + name="wearable_accordion" + top_pad="10" + width="303"> + <accordion_tab + can_resize="false" + layout="topleft" + min_height="150" + name="undershirt_main_tab" + title="Undershirt"> + <scrolling_panel_list + draw_heading="false" + follows="all" + left="0" + name="undershirt_main_param_list" + top="0" + width="303" /> + </accordion_tab> + </accordion> +</panel> + diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml new file mode 100644 index 0000000000..77b887de9b --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml @@ -0,0 +1,365 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + background_visible="true" + bevel_style="in" + follows="all" + height="570" + label="Wearable" + layout="topleft" +left="0" + name="panel_edit_wearable" + top="0" + width="333"> + <string + name="edit_shape_title"> + Editing Shape + </string> + <string + name="edit_skin_title"> + Editing Skin + </string> + <string + name="edit_hair_title"> + Editing Hair + </string> + <string + name="edit_eyes_title"> + Editing Eyes + </string> + <string + name="edit_shirt_title"> + Editing Shirt + </string> + <string + name="edit_pants_title"> + Editing Pants + </string> + <string + name="edit_shoes_title"> + Editing Shoes + </string> + <string + name="edit_socks_title"> + Editing Socks + </string> + <string + name="edit_jacket_title"> + Editing Jacket + </string> + <string + name="edit_skirt_title"> + Editing Skirt + </string> + <string + name="edit_gloves_title"> + Editing Gloves + </string> + <string + name="edit_undershirt_title"> + Editing Undershirt + </string> + <string + name="edit_underpants_title"> + Editing Underpants + </string> + <string + name="edit_alpha_title"> + Editing Alpha Mask + </string> + <string + name="edit_tattoo_title"> + Editing Tattoo + </string> + <string + name="shape_desc_text"> + Shape: + </string> + <string + name="skin_desc_text"> + Skin: + </string> + <string + name="hair_desc_text"> + Hair: + </string> + <string + name="eyes_desc_text"> + Eyes: + </string> + <string + name="shirt_desc_text"> + Shirt: + </string> + <string + name="pants_desc_text"> + Pants: + </string> + <string + name="shoes_desc_text"> + Shoes: + </string> + <string + name="socks_desc_text"> + Socks: + </string> + <string + name="jacket_desc_text"> + Jacket: + </string> + <string + name="skirt_skirt_desc_text"> + Skirt: + </string> + <string + name="gloves_desc_text"> + Gloves: + </string> + <string + name="undershirt_desc_text"> + Undershirt: + </string> + <string + name="underpants_desc_text"> + Underpants: + </string> + <string + name="alpha_desc_text"> + Alpha Mask: + </string> + <string + name="tattoo_desc_text"> + Tattoo: + </string> + <button + follows="top|left" + height="25" + width="25" + image_overlay="BackArrow_Off" + layout="topleft" + name="back_btn" + picture_style="true" + left="10" + top="7" /> + <text + follows="top|left" + font="SansSerifHugeBold" + height="22" + layout="topleft" + left_pad="15" + name="edit_wearable_title" + text_color="white" + value="Editing Shape" + width="270" /> + <panel + border="true" + follows="top|left" + height="60" + label="Shirt" + layout="topleft" + left="10" + name="wearable_type_panel" + top_pad="10" + width="313"> + <text + follows="top|left" + height="16" + layout="topleft" + left="10" + name="description_text" + value="Shape:" + width="303" /> + <text_editor + follows="all" + height="23" + left="10" + layout="topleft" + max_length="300" + name="description" + width="290" /> + </panel> + <panel + follows="all" + height="400" + layout="topleft" + left="0" + name="edit_subpanel_container" + top_pad="10" + width="333"> + <panel + filename="panel_edit_shape.xml" + follows="all" + height="400" + layout="topleft" + left="0" + name="edit_shape_panel" + top="0" + visible="false" + width="333" /> + <panel + filename="panel_edit_skin.xml" + follows="all" + height="400" + layout="topleft" + left="0" + name="edit_skin_panel" + top="0" + visible="false" + width="333" /> + <panel + filename="panel_edit_hair.xml" + follows="all" + height="400" + layout="topleft" + left="0" + name="edit_hair_panel" + top="0" + visible="false" + width="333" /> + <panel + filename="panel_edit_eyes.xml" + follows="all" + height="400" + layout="topleft" + left="0" + name="edit_eyes_panel" + top="0" + visible="false" + width="333" /> + <panel + filename="panel_edit_shirt.xml" + follows="all" + height="400" + layout="topleft" + left="0" + name="edit_shirt_panel" + top="0" + visible="false" + width="333" /> + <panel + filename="panel_edit_pants.xml" + follows="all" + height="400" + layout="topleft" + left="0" + name="edit_pants_panel" + top="0" + visible="false" + width="333" /> + <panel + filename="panel_edit_shoes.xml" + follows="all" + height="400" + layout="topleft" + left="0" + name="edit_shoes_panel" + top="0" + visible="false" + width="333" /> + <panel + filename="panel_edit_socks.xml" + follows="all" + height="400" + layout="topleft" + left="0" + name="edit_socks_panel" + top="0" + visible="false" + width="333" /> + <panel + filename="panel_edit_jacket.xml" + follows="all" + height="400" + layout="topleft" + left="0" + name="edit_jacket_panel" + top="0" + visible="false" + width="333" /> + <panel + filename="panel_edit_skirt.xml" + follows="all" + height="400" + layout="topleft" + left="0" + name="edit_skirt_panel" + top="0" + visible="false" + width="333" /> + <panel + filename="panel_edit_gloves.xml" + follows="all" + height="400" + layout="topleft" + left="0" + name="edit_gloves_panel" + top="0" + visible="false" + width="333" /> + <panel + filename="panel_edit_undershirt.xml" + follows="all" + height="400" + layout="topleft" + left="0" + name="edit_undershirt_panel" + top="0" + visible="false" + width="333" /> + <panel + filename="panel_edit_underpants.xml" + follows="all" + height="400" + layout="topleft" + left="0" + name="edit_underpants_panel" + top="0" + visible="false" + width="333" /> + <panel + filename="panel_edit_alpha.xml" + follows="all" + height="400" + layout="topleft" + left="0" + name="edit_alpha_panel" + top="0" + visible="false" + width="333" /> + <panel + filename="panel_edit_tattoo.xml" + follows="all" + height="400" + layout="topleft" + left="0" + name="edit_tattoo_panel" + top="0" + visible="false" + width="333" /> + </panel> + <panel + follows="all" + height="25" + layout="bottom|left|right" + left="0" + name="button_panel" + top_pad="10" + width="333" > + <button + follows="bottomleft" + layout="topleft" + height="23" + label="Save As" + left="10" + name="save_as_button" + top="0" + width="100" /> + <button + follows="bottomleft" + layout="topleft" + height="23" + label="Revert" + left_pad="10" + name="revert_button" + width="100" /> + </panel> +</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 index 6f01202680..c18b625033 100644 --- a/indra/newview/skins/default/xui/en/panel_group_general.xml +++ b/indra/newview/skins/default/xui/en/panel_group_general.xml @@ -24,20 +24,6 @@ Hover your mouse over the options for more help. 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" @@ -130,7 +116,7 @@ Hover your mouse over the options for more help. layout="topleft" left_delta="0" name="list_groups_in_profile" - tool_tip="Sets whether you want to show this group in your Profile" + tool_tip="Sets whether you want to show this group in your profile" top_pad="5" width="240" /> <panel @@ -161,7 +147,7 @@ Hover your mouse over the options for more help. layout="topleft" left_delta="0" name="check_enrollment_fee" - tool_tip="Sets whether to require an enrollment fee to join the group." + tool_tip="Sets whether to require an enrollment fee to join the group" top_pad="5" width="90" /> <spinner @@ -187,7 +173,7 @@ Hover your mouse over the options for more help. layout="topleft" left="4" name="show_in_group_list" - tool_tip="Let people see this group in search results." + tool_tip="Let people see this group in search results" top_pad="4" width="90" /> <combo_box @@ -195,7 +181,7 @@ Hover your mouse over the options for more help. layout="topleft" left_delta="0" name="group_mature_check" - tool_tip="Sets whether your group information is considered mature." + tool_tip="Sets whether your group information is considered mature" top_pad="10" width="240"> <combo_box.item 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 index fb4ce436e8..c3b277fb1d 100644 --- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml +++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml @@ -20,6 +20,10 @@ name="group_join_btn"> Join (L$[AMOUNT]) </panel.string> + <panel.string + name="group_join_free"> + Free + </panel.string> <button layout="topleft" name="back" @@ -87,16 +91,28 @@ top_pad="10" use_ellipses="true" width="140" /> + <text + type="string" + follows="left|top" + height="16" + layout="topleft" + left_delta="0" + name="join_cost_text" + top_pad="10" + visible="true" + width="140"> + Free + </text> <button follows="left|top" left_delta="0" top_pad="10" height="20" - label="Join" - label_selected="Join" + label="Join now!" + label_selected="Join now!" name="btn_join" visible="true" - width="65" /> + width="85" /> <button top="632" height="20" diff --git a/indra/newview/skins/default/xui/en/panel_group_invite.xml b/indra/newview/skins/default/xui/en/panel_group_invite.xml index 68b30faa1c..1996977acb 100644 --- a/indra/newview/skins/default/xui/en/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/en/panel_group_invite.xml @@ -49,7 +49,7 @@ Resident Chooser' to start. left_delta="0" multi_select="true" name="invitee_list" - tool_tip="Hold the Ctrl key and click resident names to multi-select." + tool_tip="Hold the Ctrl key and click resident names to multi-select" top_pad="4" width="200" /> <button @@ -59,7 +59,7 @@ Resident Chooser' to start. layout="topleft" left_delta="0" name="remove_button" - tool_tip="Removes residents selected above from the invite list." + tool_tip="Removes residents selected above from the invite list" top_pad="4" width="200" /> <text @@ -78,7 +78,7 @@ Resident Chooser' to start. layout="topleft" left_delta="0" name="role_name" - tool_tip="Choose from the list of Roles you are allowed to assign members to." + tool_tip="Choose from the list of Roles you are allowed to assign members to" top_delta="16" width="196" /> <button diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml index bf861af4f2..75ded4f249 100644 --- a/indra/newview/skins/default/xui/en/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml @@ -464,7 +464,7 @@ things in this group. There's a broad variety of Abilities. multi_select="true" name="action_list" search_column="1" - tool_tip="Select an Ability to view more details." + tool_tip="Select an Ability to view more details" top_pad="6" width="255"> <scroll_list.columns @@ -542,7 +542,7 @@ things in this group. There's a broad variety of Abilities. follows="left|top" left_pad="5" name="member_allowed_actions" - tool_tip="For Details of each Allowed Ability see the Abilities tab." + tool_tip="For details of each allowed ability see the abilities tab" top_delta="0" width="130"> <scroll_list.columns @@ -655,7 +655,7 @@ things in this group. There's a broad variety of Abilities. layout="topleft" left_pad="15" name="static5" - tool_tip="A list of Abilities the currently selected role can perform." + tool_tip="A list of abilities the currently selected role can perform" top_delta="0" width="100"> Allowed Abilities @@ -674,7 +674,7 @@ things in this group. There's a broad variety of Abilities. 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." + 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 @@ -684,7 +684,7 @@ things in this group. There's a broad variety of Abilities. left="135" name="role_allowed_actions" search_column="2" - tool_tip="For Details of each Allowed Ability see the Abilities tab." + tool_tip="For details of each allowed ability see the abilities tab" top="101" width="130"> <scroll_list.columns diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml index 9ee80a37d7..ad452b16a7 100644 --- a/indra/newview/skins/default/xui/en/panel_landmarks.xml +++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml @@ -1,34 +1,143 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel name="Landmarks" - bottom="0" - height="326" + top="0" + height="400" + layout="topleft" 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"/> + <accordion + follows="left|top|right|bottom" + height="368" + layout="topleft" + left="0" + name="landmarks_accordion" + top="2" + width="380"> + <accordion_tab + layout="topleft" + name="tab_favorites" + title="Favorites bar"> + <inventory_subtree_panel + allow_multi_select="true" + border="true" + bottom="0" + follows="left|top|right|bottom" + height="126" + left="0" + mouse_opaque="true" + name="favorites_list" + width="380"/> + </accordion_tab> + <accordion_tab + layout="topleft" + name="tab_landmarks" + title="Landmarks"> + <inventory_subtree_panel + allow_multi_select="true" + border="true" + bottom="0" + follows="left|top|right|bottom" + height="126" + left="0" + mouse_opaque="true" + name="landmarks_list" + start_folder="landmark" + width="380"/> + </accordion_tab> + <accordion_tab + layout="topleft" + name="tab_inventory" + title="My Inventory"> + <inventory_subtree_panel + allow_multi_select="true" + border="true" + bottom="0" + follows="left|top|right|bottom" + height="126" + left="0" + mouse_opaque="true" + name="my_inventory_list" + width="380"/> + </accordion_tab> + <accordion_tab + layout="topleft" + name="tab_library" + title="Library"> + <inventory_subtree_panel + allow_multi_select="true" + border="true" + bottom="0" + follows="left|top|right|bottom" + height="120" + left="0" + mouse_opaque="true" + name="library_list" + width="380"/> + </accordion_tab> + </accordion> + <panel + background_visible="true" + bevel_style="none" + bottom="0" + follows="left|right|bottom" + height="30" + layout="bottomleft" + left="0" + name="bottom_panel" + width="380"> + <button + follows="bottom|left" + tool_tip="Show additional options" + height="18" + image_disabled="OptionsMenu_Disabled" + image_selected="OptionsMenu_Press" + image_unselected="OptionsMenu_Off" + layout="topleft" + left="10" + name="options_gear_btn" + picture_style="true" + top="6" + width="18" /> + <button + follows="bottom|left" + height="18" + image_selected="AddItem_Press" + image_unselected="AddItem_Off" + image_disabled="AddItem_Disabled" + layout="topleft" + left_pad="5" + name="add_landmark_btn" + picture_style="true" + tool_tip="Add new landmark" + width="18" /> + <button + follows="bottom|left" + height="18" + image_selected="AddItem_Press" + image_unselected="AddItem_Off" + image_disabled="AddItem_Disabled" + layout="topleft" + left_pad="5" + name="add_folder_btn" + picture_style="true" + tool_tip="Add new folder" + width="18" /> + <button + follows="bottom|right" + height="18" + image_selected="TrashItem_Press" + image_unselected="TrashItem_Off" + layout="topleft" + right="-5" + name="trash_btn" + picture_style="true" + tool_tip="Remove selected landmark" + top="6" + width="18" /> + </panel> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_notification.xml b/indra/newview/skins/default/xui/en/panel_notification.xml new file mode 100644 index 0000000000..4d890b1d46 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_notification.xml @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + background_opaque="true" + background_visible="false" + bg_alpha_color="0.3 0.3 0.3 0" + height="140" + label="notification_panel" + layout="topleft" + left="0" + name="notification_panel" + top="0" + width="350"> + <panel + background_visible="true" + follows="left|right|top" + height="100" + label="info_panel" + layout="topleft" + left="0" + name="info_panel" + top="0" + width="350"> + <text + border_visible="false" + follows="left|right|top|bottom" + font="SansSerif" + height="90" + layout="topleft" + left="45" + name="text_box" + read_only="true" + text_color="white" + top="5" + visible="false" + width="300" + wrap="true"/> + <text + border_visible="false" + follows="left|right|top|bottom" + font="SansSerifBold" + height="90" + layout="topleft" + left="45" + name="caution_text_box" + text_color="1 0.82 0.46 1" + top="5" + visible="false" + width="300" + wrap="true"/> + <text_editor + bg_readonly_color="0.0 0.0 0.0 0" + border_visible="false" + embedded_items="false" + enabled="false" + follows="left|right|top|bottom" + font="SansSerif" + height="90" + layout="topleft" + left="45" + mouse_opaque="false" + name="text_editor_box" + read_only="true" + tab_stop="false" + text_color="white" + text_readonly_color="white" + top="5" + visible="false" + width="300" + wrap="true"/> + </panel> + <panel + background_visible="true" + follows="left|right|bottom" + height="40" + label="control_panel" + layout="topleft" + left="0" + name="control_panel" + top_pad="0" + width="350"> + </panel> + <icon + follows="left|top" + height="32" + image_name="notify_tip_icon.tga" + layout="topleft" + left="8" + mouse_opaque="false" + name="info_icon" + top="20" + width="32" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index b51d53a1b4..e53edf891d 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -86,8 +86,7 @@ color="DkGray" width="313"> <button follows="bottom|left" - font="SansSerifBigBold" - tool_tip="Change sort and view of Residents list" + tool_tip="Change sort and view of residents list" height="18" image_disabled="OptionsMenu_Disabled" image_selected="OptionsMenu_Press" @@ -166,8 +165,7 @@ color="DkGray" width="313"> <button follows="bottom|left" - font="SansSerifBigBold" - tool_tip="Change sort and view of Friends list" + tool_tip="Change sort and view of friends list" height="18" image_disabled="OptionsMenu_Disabled" image_selected="OptionsMenu_Press" @@ -180,7 +178,6 @@ color="DkGray" width="18" /> <button follows="bottom|left" - font="SansSerifBigBold" height="18" image_selected="AddItem_Press" image_unselected="AddItem_Off" @@ -194,7 +191,6 @@ color="DkGray" width="18" /> <button follows="bottom|left" - font="SansSerifBigBold" height="18" image_selected="TrashItem_Press" image_unselected="TrashItem_Off" @@ -211,7 +207,7 @@ color="DkGray" <panel background_visible="true" bevel_style="none" - follows="left|top|right|bottom" + follows="all" height="390" label="Groups" top="0" @@ -220,7 +216,7 @@ color="DkGray" name="groups_panel" width="313"> <group_list - follows="left|top|right|bottom" + follows="all" height="357" layout="topleft" color="DkGray2" @@ -241,8 +237,7 @@ color="DkGray" width="313"> <button follows="bottom|left" - font="SansSerifBigBold" - tool_tip="Change sort and view of Groups list" + tool_tip="Change sort and view of groups list" height="18" image_disabled="OptionsMenu_Disabled" image_selected="OptionsMenu_Press" @@ -255,7 +250,6 @@ color="DkGray" width="18" /> <button follows="bottom|left" - font="SansSerifBigBold" height="18" image_selected="AddItem_Press" image_unselected="AddItem_Off" @@ -269,11 +263,10 @@ color="DkGray" 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" + image_hover_selected="Activate_Checkmark" + image_selected="Activate_Checkmark" + image_unselected="Activate_Checkmark" layout="topleft" left_pad="24" name="activate_btn" @@ -283,7 +276,6 @@ color="DkGray" width="10" /> <button follows="bottom|left" - font="SansSerifBigBold" height="18" image_selected="TrashItem_Press" image_unselected="TrashItem_Off" @@ -300,7 +292,7 @@ color="DkGray" background_visible="true" bevel_style="none" top="0" - follows="left|top|right|bottom" + follows="all" height="390" label="Recent" layout="topleft" @@ -309,7 +301,7 @@ color="DkGray" width="313"> <avatar_list color="DkGray2" - follows="left|top|right|bottom" + follows="all" height="357" layout="topleft" left="0" @@ -330,7 +322,7 @@ color="DkGray" <button follows="bottom|left" font="SansSerifBigBold" - tool_tip="Change sort and view of Recent Residents list" + tool_tip="Change sort and view of recent residents list" height="18" image_disabled="OptionsMenu_Disabled" image_selected="OptionsMenu_Press" @@ -390,7 +382,7 @@ color="DkGray" label="Add Friend" layout="topleft" name="add_friend_btn" - tool_tip="Add selected resident to your Friends List" + tool_tip="Add selected resident to your friends List" width="85" /> </layout_panel> <layout_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 index 7d5ae3d78a..a67ae59b4a 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_info.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml @@ -1,43 +1,47 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel - bevel_style="in" - follows="left|top|right|bottom" + background_visible="true" + follows="all" height="570" layout="topleft" left="0" + min_height="350" name="panel_pick_info" top="0" width="333"> <button - follows="top|left" - height="25" - width="25" + follows="top|right" + height="23" image_overlay="BackArrow_Off" layout="topleft" name="back_btn" picture_style="true" left="10" - top="7" /> + tab_stop="false" + top="2" + width="23" /> <text - follows="top|left" + follows="top|left|right" font="SansSerifHugeBold" - height="22" + height="26" layout="topleft" - left_pad="15" + left_pad="10" name="title" text_color="white" + top="0" value="Pick Info" - width="270" /> + use_elipsis="true" + width="275" /> <scroll_container color="DkGray2" opaque="true" follows="all" - height="470" + height="500" layout="topleft" left="10" top_pad="10" name="profile_scroll" - reserve_scroll_corner="true" + reserve_scroll_corner="false" width="313"> <panel name="scroll_content_panel" @@ -57,11 +61,11 @@ left="10" name="pick_snapshot" top="20" - width="280" /> + width="290" /> <text follows="left|top|right" - height="20" - width="280" + height="35" + width="290" layout="topleft" font="SansSerifBig" font.style="BOLD" @@ -70,14 +74,14 @@ name="pick_name" text_color="white" value="[name]" - word_wrap="true" /> + use_ellipses="true" /> <text follows="left|top" height="25" layout="topleft" left="10" name="pick_location" - width="280" + width="290" word_wrap="true" value="[loading...]" /> <text @@ -86,47 +90,47 @@ layout="topleft" left="10" name="pick_desc" - width="280" + width="290" value="[description]" word_wrap="true" /> </panel> </scroll_container> <panel follows="left|right|bottom" - height="30" + height="20" layout="topleft" - top_pad="5" + top_pad="8" left="10" name="buttons"> <button follows="bottom|left" - font="SansSerifSmallBold" - height="25" - label="Edit" + font="SansSerifSmall" + height="19" + label="Teleport" layout="topleft" left="0" - name="edit_btn" + name="teleport_btn" top="0" - width="80" /> + width="90" /> <button follows="bottom|left" - font="SansSerifSmallBold" - height="25" - label="Teleport" + font="SansSerifSmall" + height="19" + label="Map" layout="topleft" - left_pad="5" - name="teleport_btn" + left_pad="10" + name="show_on_map_btn" top="0" - width="80" /> + width="90" /> <button follows="bottom|left" - font="SansSerifSmallBold" - height="25" - label="Map" + font="SansSerifSmall" + height="19" + label="Edit" layout="topleft" - left_pad="5" - name="show_on_map_btn" + right="-1" + name="edit_btn" top="0" - width="80" /> + width="90" /> </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 index 686faab8eb..1074dd4627 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml @@ -2,79 +2,82 @@ <panel bevel_style="none" follows="top|left|right" - height="120" + height="85" layout="topleft" left="0" name="picture_item" top="0" - width="305"> + width="313"> <icon - follows="top|bottom|left|right" - height="120" + follows="all" + height="85" image_name="ListItem_Over" - left="0" + right="-3" mouse_opaque="false" name="hovered_icon" - top="0" + top="1" scale_image="true" visible="false" - width="305"/> + width="307"/> <icon - follows="top|bottom|left|right" - height="120" + follows="all" + height="85" image_name="ListItem_Select" - left="0" + right="-3" mouse_opaque="false" name="selected_icon" - top="0" + top="1" scale_image="true" visible="false" - width="305"/> + width="307"/> <texture_picker allow_no_texture="true" - default_image_name="None" + border_enabled="true" + default_image_name="TabIcon_Places_Large" enabled="false" follows="left|top" - height="120" + height="80" layout="topleft" - left="5" + left="10" mouse_opaque="false" name="picture" tab_stop="false" - top="5" - top_pad="5" - width="120" /> + top="10" + top_pad="10" + width="90" /> <text follows="top|left|right" + font="SansSerifSmallBold" height="16" layout="topleft" - left="135" + left="110" name="picture_name" text_color="white" - top="5" - use_ellipses="true" - width="130" - word_wrap="true" /> + top="9" + use_ellipses="false" + width="197" + word_wrap="false" /> <text follows="top|left|right" - height="75" + font="SansSerifSmall" + height="40" layout="topleft" - left="135" + left="110" name="picture_descr" - top_pad="10" - use_ellipses="true" - width="130" + top_pad="3" + width="178" word_wrap="true" /> <button follows="top|right" height="16" - image_selected="Info_Press" - image_unselected="Info_Off" + image_selected="BuyArrow_Press" + image_pressed="BuyArrow_Press" + image_unselected="BuyArrow_Press" layout="topleft" name="info_chevron" picture_style="true" - right="290" + right="-7" tab_stop="false" - top="5" + top="27" 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 index 2869ec78f4..ac2cf19a96 100644 --- a/indra/newview/skins/default/xui/en/panel_picks.xml +++ b/indra/newview/skins/default/xui/en/panel_picks.xml @@ -54,7 +54,7 @@ left_pad="15" name="new_btn" picture_style="true" - tool_tip="Create New Pick at Current Location" + tool_tip="Create new pick at current location" top="5" width="18" /> <button diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml index ba933683e3..a32be90a33 100644 --- a/indra/newview/skins/default/xui/en/panel_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_profile.xml @@ -36,10 +36,12 @@ name="profile_scroll" reserve_scroll_corner="true" opaque="true" - top="0"> + top="0" + width="313"> <panel name="scroll_content_panel" follows="left|top|right" + height="485" layout="topleft" top="0" left="0" @@ -51,7 +53,7 @@ left="10" name="second_life_image_panel" top="0" - width="285"> + width="290"> <texture_picker allow_no_texture="true" default_image_name="None" @@ -76,8 +78,9 @@ width="170" /> <expandable_text follows="left|top|right" - height="90" + height="95" layout="topleft" + left="107" name="sl_description_edit" width="173" expanded_bg_visible="true" @@ -92,7 +95,7 @@ top_pad="10" left="10" name="first_life_image_panel" - width="285"> + width="290"> <texture_picker allow_no_texture="true" default_image_name="None" @@ -116,10 +119,11 @@ width="173" /> <expandable_text follows="left|top|right" - height="90" + height="95" layout="topleft" + left="107" name="fl_description_edit" - width="170" + width="173" expanded_bg_visible="true" expanded_bg_color="DkGray"> 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. @@ -265,7 +269,8 @@ name="profile_buttons_panel" top_pad="2" bottom="10" - height="19"> + height="19" + width="313"> <button follows="bottom|left" height="19" @@ -319,12 +324,14 @@ follows="bottom|left" layout="topleft" left="0" + top_pad="-17" name="profile_me_buttons_panel" - top_pad="-3" visible="false" - height="19"> + height="19" + width="313"> <button follows="bottom|right" + font="SansSerifSmall" height="19" left="10" label="Edit Profile" diff --git a/indra/newview/skins/default/xui/en/panel_region_debug.xml b/indra/newview/skins/default/xui/en/panel_region_debug.xml index 78e5678455..25e1171688 100644 --- a/indra/newview/skins/default/xui/en/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/en/panel_region_debug.xml @@ -162,7 +162,7 @@ layout="topleft" left_delta="60" name="return_scripts" - tool_tip="Return only objects which have scripts." + tool_tip="Return only objects which have scripts" top_delta="0" width="80" /> <check_box diff --git a/indra/newview/skins/default/xui/en/panel_region_estate.xml b/indra/newview/skins/default/xui/en/panel_region_estate.xml index afcefcbd3b..c7a60ed2e4 100644 --- a/indra/newview/skins/default/xui/en/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/en/panel_region_estate.xml @@ -180,7 +180,7 @@ regions in the estate. layout="topleft" left_delta="0" name="limit_payment" - tool_tip="Ban unidentified residents." + tool_tip="Ban unidentified residents" top_pad="2" width="278" /> <check_box 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 index 4d91a544c3..c8703aa895 100644 --- a/indra/newview/skins/default/xui/en/panel_stand_stop_flying.xml +++ b/indra/newview/skins/default/xui/en/panel_stand_stop_flying.xml @@ -4,12 +4,12 @@ height="25" layout="topleft" name="panel_stand_stop_flying" - mouse_opaque="false" - visible="false" + mouse_opaque="false" + visible="false" width="115"> <button follows="left|bottom" - height="20" + height="19" label="Stand" layout="topleft" name="stand_btn" @@ -19,11 +19,11 @@ width="115" /> <button follows="left|bottom" - height="20" + height="19" label="Stop Flying" layout="topleft" name="stop_fly_btn" - tool_tip="Stop Flying" + tool_tip="Stop flying" top="2" visible="false" width="115" /> diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml index fc61ce9683..795e0ffc0d 100644 --- a/indra/newview/skins/default/xui/en/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml @@ -68,7 +68,7 @@ left_pad="20" name="TimeText" text_color="TimeTextColor" - tool_tip="Current Time (Pacific)" + tool_tip="Current time (Pacific)" width="80"> 12:00 AM </text> @@ -82,7 +82,7 @@ name="scriptout" picture_style="true" scale_image="false" - tool_tip="Script Warnings and Errors" + tool_tip="Script warnings and errors" top="0" visible="false" width="16" /> @@ -140,7 +140,7 @@ name="no_build" picture_style="true" scale_image="false" - tool_tip="Building/Rezzing not allowed" + tool_tip="Building/rezzing not allowed" top="0" visible="false" width="16" /> @@ -168,7 +168,7 @@ name="restrictpush" picture_style="true" scale_image="false" - tool_tip="No Pushing" + tool_tip="No pushing" top="0" visible="false" width="16" /> diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history.xml b/indra/newview/skins/default/xui/en/panel_teleport_history.xml index b0cd75117f..4169c6245b 100644 --- a/indra/newview/skins/default/xui/en/panel_teleport_history.xml +++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml @@ -1,15 +1,6 @@ <?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"> - <string - name="cant_create_lm_here" - value="Please teleport to selected location before creating Landmark. " /> - <string - name="create_landmark" - value="Create Landmark" /> - <string - name="open_landmark" - value="Open Landmark panel" /> <accordion follows="left|top|right|bottom" height="300" @@ -188,19 +179,5 @@ picture_style="true" top="5" width="18" /> - <button - follows="bottom|left" - font="SansSerifBigBold" - height="18" - image_selected="Favorite_Star_Active" - image_disabled="Favorite_Star_Off" - image_unselected="Favorite_Star_Press" - layout="topleft" - left_pad="5" - name="star_btn" - picture_style="true" - tool_tip="" - top_delta="0" - width="18" /> </panel> </panel> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 2a616d8e2f..d13f5dbde3 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -1951,6 +1951,10 @@ this texture in your inventory <string name="AgeDaysA">[COUNT] day</string> <string name="AgeDaysB">[COUNT] days</string> <string name="AgeDaysC">[COUNT] days</string> + <!-- Group member counts --> + <string name="GroupMembersA">[COUNT] member</string> + <string name="GroupMembersB">[COUNT] members</string> + <string name="GroupMembersC">[COUNT] members</string> <!-- Account types, see LLAvatarPropertiesProcessor --> <string name="AcctTypeResident">Resident</string> diff --git a/indra/newview/skins/default/xui/en/widgets/button.xml b/indra/newview/skins/default/xui/en/widgets/button.xml index 3e7e07749a..5bb48ef5aa 100644 --- a/indra/newview/skins/default/xui/en/widgets/button.xml +++ b/indra/newview/skins/default/xui/en/widgets/button.xml @@ -11,6 +11,7 @@ image_color="ButtonImageColor" image_color_disabled="ButtonImageColor" flash_color="ButtonFlashBgColor" + font="SansSerifSmall" hover_glow_amount="0.15" halign="center" scale_image="true"> diff --git a/indra/newview/skins/default/xui/en/widgets/chat_history.xml b/indra/newview/skins/default/xui/en/widgets/chat_history.xml new file mode 100644 index 0000000000..b72d59524e --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/chat_history.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<chat_history + message_header="panel_chat_header.xml" + message_separator="panel_chat_separator.xml" + left_text_pad="10" + right_text_pad="15" + left_widget_pad="5" + rigth_widget_pad="10" + max_length="2147483647" + enabled="false" + track_bottom="true" + name="chat_history" + type="string" + word_wrap="true" />
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/widgets/combo_box.xml b/indra/newview/skins/default/xui/en/widgets/combo_box.xml index 8b23b72c2d..9ed3749308 100644 --- a/indra/newview/skins/default/xui/en/widgets/combo_box.xml +++ b/indra/newview/skins/default/xui/en/widgets/combo_box.xml @@ -15,7 +15,7 @@ label="" hover_glow_amount="0.15" font="SansSerifSmall" - scale_image="false" + scale_image="true" pad_right="24" image_unselected="DropDown_Off" image_selected="DropDown_Selected" diff --git a/indra/newview/skins/default/xui/en/widgets/location_input.xml b/indra/newview/skins/default/xui/en/widgets/location_input.xml index d86103aedc..40c8dc860d 100644 --- a/indra/newview/skins/default/xui/en/widgets/location_input.xml +++ b/indra/newview/skins/default/xui/en/widgets/location_input.xml @@ -46,7 +46,7 @@ <combo_button name="Location History" label="" pad_right="0" - tool_tip="My Location History"/> + tool_tip="My location history"/> <combo_list bg_writeable_color="MenuDefaultBgColor" page_lines="10" scroll_bar_bg_visible="true" /> <combo_editor name="Combo Text Entry" diff --git a/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml b/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml index a054b4ee60..769af42e38 100644 --- a/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml +++ b/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml @@ -13,7 +13,7 @@ <combo_editor name="child1" select_on_focus="true" - text_pad_left="20" + text_pad_left="28" tool_tip="Search" background_image="TextField_Search_Off" background_image_disabled="TextField_Search_Disabled" @@ -24,9 +24,9 @@ page_lines="10" scroll_bar_bg_visible="true" /> <search_button label="" + top_pad="5" + left_pad="10" name="child3" - top_pad="4" - left_pad="4" width="13" height="13" tool_tip="Search" |