@@ -21,12 +21,18 @@ namespace OpenRA.Mods.Common.Widgets.Logic
21
21
{
22
22
public class LocalProfileLogic : ChromeLogic
23
23
{
24
+ readonly WorldRenderer worldRenderer ;
24
25
readonly LocalPlayerProfile localProfile ;
26
+ readonly Widget badgeContainer ;
27
+ readonly Widget widget ;
25
28
bool notFound ;
29
+ bool badgesVisible ;
26
30
27
31
[ ObjectCreator . UseCtor ]
28
32
public LocalProfileLogic ( Widget widget , WorldRenderer worldRenderer , Func < bool > minimalProfile )
29
33
{
34
+ this . worldRenderer = worldRenderer ;
35
+ this . widget = widget ;
30
36
localProfile = Game . LocalPlayerProfile ;
31
37
32
38
// Key registration
@@ -78,6 +84,10 @@ public LocalProfileLogic(Widget widget, WorldRenderer worldRenderer, Func<bool>
78
84
destroyKey . OnClick = localProfile . DeleteKeypair ;
79
85
destroyKey . IsDisabled = minimalProfile ;
80
86
87
+ badgeContainer = widget . Get ( "BADGES_CONTAINER" ) ;
88
+ badgeContainer . IsVisible = ( ) => badgesVisible && ! minimalProfile ( )
89
+ && localProfile . State == LocalPlayerProfile . LinkState . Linked ;
90
+
81
91
localProfile . RefreshPlayerData ( ( ) => RefreshComplete ( false ) ) ;
82
92
}
83
93
@@ -86,7 +96,36 @@ public void RefreshComplete(bool updateNotFound)
86
96
if ( updateNotFound )
87
97
notFound = localProfile . State == LocalPlayerProfile . LinkState . Unlinked ;
88
98
89
- Game . RunAfterTick ( Ui . ResetTooltips ) ;
99
+ Game . RunAfterTick ( ( ) =>
100
+ {
101
+ badgesVisible = false ;
102
+
103
+ if ( localProfile . State == LocalPlayerProfile . LinkState . Linked )
104
+ {
105
+ if ( localProfile . ProfileData . Badges . Any ( ) )
106
+ {
107
+ Func < int , int > negotiateWidth = _ => widget . Get ( "PROFILE_HEADER" ) . Bounds . Width ;
108
+
109
+ // Remove any stale badges that may be left over from a previous session
110
+ badgeContainer . RemoveChildren ( ) ;
111
+
112
+ var badges = Ui . LoadWidget ( "PLAYER_PROFILE_BADGES_INSERT" , badgeContainer , new WidgetArgs ( )
113
+ {
114
+ { "worldRenderer" , worldRenderer } ,
115
+ { "profile" , localProfile . ProfileData } ,
116
+ { "negotiateWidth" , negotiateWidth }
117
+ } ) ;
118
+
119
+ if ( badges . Bounds . Height > 0 )
120
+ {
121
+ badgeContainer . Bounds . Height = badges . Bounds . Height ;
122
+ badgesVisible = true ;
123
+ }
124
+ }
125
+ }
126
+
127
+ Ui . ResetTooltips ( ) ;
128
+ } ) ;
90
129
}
91
130
}
92
131
@@ -102,6 +141,8 @@ public RegisteredProfileTooltipLogic(Widget widget, WorldRenderer worldRenderer,
102
141
playerDatabase = modData . Manifest . Get < PlayerDatabase > ( ) ;
103
142
104
143
var header = widget . Get ( "HEADER" ) ;
144
+ var badgeContainer = widget . Get ( "BADGES_CONTAINER" ) ;
145
+ var badgeSeparator = badgeContainer . GetOrNull ( "SEPARATOR" ) ;
105
146
106
147
var profileHeader = header . Get ( "PROFILE_HEADER" ) ;
107
148
var messageHeader = header . Get ( "MESSAGE_HEADER" ) ;
@@ -145,18 +186,45 @@ public RegisteredProfileTooltipLogic(Widget widget, WorldRenderer worldRenderer,
145
186
profileWidth = Math . Max ( profileWidth , rankFont . Measure ( profile . ProfileRank ) . X + 2 * rankLabel . Bounds . Left ) ;
146
187
147
188
header . Bounds . Height += headerSizeOffset ;
189
+ badgeContainer . Bounds . Y += header . Bounds . Height ;
148
190
if ( client . IsAdmin )
149
191
{
150
192
profileWidth = Math . Max ( profileWidth , adminFont . Measure ( adminLabel . Text ) . X + 2 * adminLabel . Bounds . Left ) ;
151
193
152
194
adminContainer . IsVisible = ( ) => true ;
153
195
profileHeader . Bounds . Height += adminLabel . Bounds . Height ;
154
196
header . Bounds . Height += adminLabel . Bounds . Height ;
197
+ badgeContainer . Bounds . Y += adminLabel . Bounds . Height ;
198
+ }
199
+
200
+ Func < int , int > negotiateWidth = badgeWidth =>
201
+ {
202
+ profileWidth = Math . Min ( Math . Max ( badgeWidth , profileWidth ) , widget . Bounds . Width ) ;
203
+ return profileWidth ;
204
+ } ;
205
+
206
+ if ( profile . Badges . Any ( ) )
207
+ {
208
+ var badges = Ui . LoadWidget ( "PLAYER_PROFILE_BADGES_INSERT" , badgeContainer , new WidgetArgs ( )
209
+ {
210
+ { "worldRenderer" , worldRenderer } ,
211
+ { "profile" , profile } ,
212
+ { "negotiateWidth" , negotiateWidth }
213
+ } ) ;
214
+
215
+ if ( badges . Bounds . Height > 0 )
216
+ {
217
+ badgeContainer . Bounds . Height = badges . Bounds . Height ;
218
+ badgeContainer . IsVisible = ( ) => true ;
219
+ }
155
220
}
156
221
157
222
profileWidth = Math . Min ( profileWidth , widget . Bounds . Width ) ;
158
- header . Bounds . Width = widget . Bounds . Width = profileWidth ;
159
- widget . Bounds . Height = header . Bounds . Height ;
223
+ header . Bounds . Width = widget . Bounds . Width = badgeContainer . Bounds . Width = profileWidth ;
224
+ widget . Bounds . Height = header . Bounds . Height + badgeContainer . Bounds . Height ;
225
+
226
+ if ( badgeSeparator != null )
227
+ badgeSeparator . Bounds . Width = profileWidth - 2 * badgeSeparator . Bounds . X ;
160
228
161
229
profileLoaded = true ;
162
230
} ) ;
@@ -182,11 +250,53 @@ public RegisteredProfileTooltipLogic(Widget widget, WorldRenderer worldRenderer,
182
250
header . Bounds . Height += messageHeader . Bounds . Height ;
183
251
header . Bounds . Width = widget . Bounds . Width = messageWidth ;
184
252
widget . Bounds . Height = header . Bounds . Height ;
253
+ badgeContainer . Visible = false ;
185
254
186
255
new Download ( playerDatabase . Profile + client . Fingerprint , _ => { } , onQueryComplete ) ;
187
256
}
188
257
}
189
258
259
+ public class PlayerProfileBadgesLogic : ChromeLogic
260
+ {
261
+ [ ObjectCreator . UseCtor ]
262
+ public PlayerProfileBadgesLogic ( Widget widget , PlayerProfile profile , Func < int , int > negotiateWidth )
263
+ {
264
+ var showBadges = profile . Badges . Any ( ) ;
265
+ widget . IsVisible = ( ) => showBadges ;
266
+
267
+ var badgeTemplate = widget . Get ( "BADGE_TEMPLATE" ) ;
268
+ widget . RemoveChild ( badgeTemplate ) ;
269
+
270
+ var width = 0 ;
271
+ var badgeOffset = badgeTemplate . Bounds . Y ;
272
+ foreach ( var badge in profile . Badges )
273
+ {
274
+ var b = badgeTemplate . Clone ( ) ;
275
+ var icon = b . Get < SpriteWidget > ( "ICON" ) ;
276
+ icon . GetSprite = ( ) => badge . Icon24 ;
277
+
278
+ var label = b . Get < LabelWidget > ( "LABEL" ) ;
279
+ var labelFont = Game . Renderer . Fonts [ label . Font ] ;
280
+
281
+ var labelText = WidgetUtils . TruncateText ( badge . Label , label . Bounds . Width , labelFont ) ;
282
+ label . GetText = ( ) => labelText ;
283
+
284
+ width = Math . Max ( width , label . Bounds . Left + labelFont . Measure ( labelText ) . X + icon . Bounds . X ) ;
285
+
286
+ b . Bounds . Y = badgeOffset ;
287
+ widget . AddChild ( b ) ;
288
+
289
+ badgeOffset += badgeTemplate . Bounds . Height ;
290
+ }
291
+
292
+ if ( badgeOffset > badgeTemplate . Bounds . Y )
293
+ badgeOffset += 5 ;
294
+
295
+ widget . Bounds . Width = negotiateWidth ( width ) ;
296
+ widget . Bounds . Height = badgeOffset ;
297
+ }
298
+ }
299
+
190
300
public class AnonymousProfileTooltipLogic : ChromeLogic
191
301
{
192
302
[ ObjectCreator . UseCtor ]
0 commit comments