|
Lines 43-48
Link Here
|
| 43 |
#region Private Fields |
43 |
#region Private Fields |
| 44 |
|
44 |
|
| 45 |
private List<FragmentControlProvider> children; |
45 |
private List<FragmentControlProvider> children; |
|
|
46 |
private List<Component> componentChildren; |
| 46 |
private INavigation navigation; |
47 |
private INavigation navigation; |
| 47 |
private SWF.ContextMenu contextMenu; |
48 |
private SWF.ContextMenu contextMenu; |
| 48 |
private SWF.ContextMenuStrip contextMenuStrip; |
49 |
private SWF.ContextMenuStrip contextMenuStrip; |
|
Lines 63-68
Link Here
|
| 63 |
componentProviders = |
64 |
componentProviders = |
| 64 |
new Dictionary<Component, FragmentControlProvider> (); |
65 |
new Dictionary<Component, FragmentControlProvider> (); |
| 65 |
children = new List<FragmentControlProvider> (); |
66 |
children = new List<FragmentControlProvider> (); |
|
|
67 |
componentChildren = new List<Component> (); |
| 66 |
|
68 |
|
| 67 |
if (Control != null) { |
69 |
if (Control != null) { |
| 68 |
Control.ContextMenuChanged += HandleContextMenuChanged; |
70 |
Control.ContextMenuChanged += HandleContextMenuChanged; |
|
Lines 223-252
Link Here
|
| 223 |
// aren't sent to bridge until the parent's already |
225 |
// aren't sent to bridge until the parent's already |
| 224 |
// there. There are about 100 ways to do this |
226 |
// there. There are about 100 ways to do this |
| 225 |
// better. |
227 |
// better. |
| 226 |
if (Control != null) { |
228 |
if (Control != null) { |
| 227 |
Control.ControlAdded += OnControlAdded; |
229 |
Control.ControlAdded += OnControlAdded; |
| 228 |
Control.ControlRemoved += OnControlRemoved; |
230 |
Control.ControlRemoved += OnControlRemoved; |
| 229 |
|
231 |
|
| 230 |
foreach (SWF.Control childControl in Control.Controls) { |
232 |
foreach (SWF.Control childControl in Control.Controls) |
| 231 |
FragmentControlProvider childProvider = |
233 |
HandleComponentAdded (childControl, false); |
| 232 |
CreateProvider (childControl); |
|
|
| 233 |
|
| 234 |
if (childProvider == null) |
| 235 |
continue; |
| 236 |
// TODO: Null check, compound, etc? |
| 237 |
|
| 238 |
componentProviders [childControl] = childProvider; |
| 239 |
OnNavigationChildAdded (false, |
| 240 |
(FragmentControlProvider) childProvider); |
| 241 |
} |
| 242 |
} |
234 |
} |
| 243 |
} |
235 |
} |
| 244 |
|
236 |
|
| 245 |
public virtual void FinalizeChildControlStructure () |
237 |
public virtual void FinalizeChildControlStructure () |
| 246 |
{ |
238 |
{ |
| 247 |
for (; children.Count > 0; ) |
239 |
for (; componentChildren.Count > 0; ) |
| 248 |
OnNavigationChildRemoved (false, |
240 |
HandleComponentRemoved (componentChildren [0], false); |
| 249 |
(FragmentControlProvider) children [0]); |
|
|
| 250 |
|
241 |
|
| 251 |
children.Clear (); |
242 |
children.Clear (); |
| 252 |
componentProviders.Clear (); |
243 |
componentProviders.Clear (); |
|
Lines 320-356
Link Here
|
| 320 |
|
311 |
|
| 321 |
private void OnControlAdded (object sender, SWF.ControlEventArgs args) |
312 |
private void OnControlAdded (object sender, SWF.ControlEventArgs args) |
| 322 |
{ |
313 |
{ |
| 323 |
SWF.Control childControl = args.Control; |
314 |
HandleComponentAdded (args.Control, true); |
| 324 |
FragmentControlProvider childProvider = CreateProvider (childControl); |
|
|
| 325 |
if (childProvider == null) |
| 326 |
return; |
| 327 |
|
| 328 |
componentProviders [childControl] = childProvider; |
| 329 |
OnNavigationChildAdded (true, |
| 330 |
(FragmentControlProvider) childProvider); |
| 331 |
} |
315 |
} |
| 332 |
|
316 |
|
| 333 |
private void OnControlRemoved (object sender, SWF.ControlEventArgs args) |
317 |
private void OnControlRemoved (object sender, SWF.ControlEventArgs args) |
| 334 |
{ |
318 |
{ |
| 335 |
FragmentControlProvider removedProvider; |
319 |
HandleComponentRemoved (args.Control, true); |
| 336 |
|
|
|
| 337 |
if (componentProviders.TryGetValue (args.Control, out removedProvider) == true) { |
| 338 |
|
| 339 |
// TODO: Some sort of disposal |
| 340 |
|
| 341 |
componentProviders.Remove (args.Control); |
| 342 |
// StructureChangedEvent |
| 343 |
// TODO: Use correct arguments, and fix bridge |
| 344 |
// to handle them!!! |
| 345 |
// Event source: Parent of removed child |
| 346 |
// runtimeId: The child that was removed. |
| 347 |
// (pg 6 of fxref_uiautomationtypes_p2.pdf) |
| 348 |
OnNavigationChildRemoved (true, |
| 349 |
(FragmentControlProvider) removedProvider); |
| 350 |
ProviderFactory.ReleaseProvider (args.Control); |
| 351 |
} |
| 352 |
} |
320 |
} |
| 353 |
|
321 |
|
|
|
322 |
private void OnNotVisibleControlVisibleChanged (object sender, EventArgs args) |
| 323 |
{ |
| 324 |
SWF.Control control = (SWF.Control) sender; |
| 325 |
|
| 326 |
if (control.Visible) |
| 327 |
InitializeComponentProvider (control, true); |
| 328 |
else |
| 329 |
TerminateComponentProvider (control, true); |
| 330 |
} |
| 331 |
|
| 354 |
#endregion |
332 |
#endregion |
| 355 |
|
333 |
|
| 356 |
#region Protected Methods |
334 |
#region Protected Methods |
|
Lines 362-367
Link Here
|
| 362 |
|
340 |
|
| 363 |
return (FragmentControlProvider) ProviderFactory.GetProvider (control); |
341 |
return (FragmentControlProvider) ProviderFactory.GetProvider (control); |
| 364 |
} |
342 |
} |
|
|
343 |
|
| 344 |
protected virtual FragmentControlProvider CreateProvider (Component component) |
| 345 |
{ |
| 346 |
return (FragmentControlProvider) ProviderFactory.GetProvider (component); |
| 347 |
} |
| 348 |
|
| 349 |
protected virtual void DestroyProvider (Component component) |
| 350 |
{ |
| 351 |
ProviderFactory.ReleaseProvider (component); |
| 352 |
} |
| 365 |
|
353 |
|
| 366 |
protected FragmentControlProvider GetProvider (SWF.Control control) |
354 |
protected FragmentControlProvider GetProvider (SWF.Control control) |
| 367 |
{ |
355 |
{ |
|
Lines 371-377
Link Here
|
| 371 |
return null; |
359 |
return null; |
| 372 |
} |
360 |
} |
| 373 |
|
361 |
|
|
|
362 |
protected void InitializeComponentProvider (Component childComponent, |
| 363 |
bool raiseEvent) |
| 364 |
{ |
| 365 |
SWF.Control control = null; |
| 366 |
FragmentControlProvider childProvider = null; |
| 367 |
|
| 368 |
if ((control = childComponent as SWF.Control) != null) |
| 369 |
childProvider = CreateProvider (control); |
| 370 |
else |
| 371 |
childProvider = CreateProvider (childComponent); |
| 372 |
|
| 373 |
if (childProvider == null) |
| 374 |
return; |
| 375 |
// TODO: Null check, compound, etc? |
| 376 |
|
| 377 |
componentProviders [childComponent] = childProvider; |
| 378 |
OnNavigationChildAdded (raiseEvent, childProvider); |
| 379 |
} |
| 380 |
|
| 381 |
protected void TerminateComponentProvider (Component childComponent, |
| 382 |
bool raiseEvent) |
| 383 |
{ |
| 384 |
FragmentControlProvider removedProvider; |
| 385 |
|
| 386 |
if (componentProviders.TryGetValue (childComponent, |
| 387 |
out removedProvider)) { |
| 388 |
componentProviders.Remove (childComponent); |
| 389 |
// Event source: |
| 390 |
// Parent of removed child runtimeId: The child that was |
| 391 |
// removed. (pg 6 of fxref_uiautomationtypes_p2.pdf) |
| 392 |
OnNavigationChildRemoved (raiseEvent, removedProvider); |
| 393 |
DestroyProvider (childComponent); |
| 394 |
} |
| 395 |
} |
| 396 |
|
| 397 |
protected void AddChildComponent (Component childComponent) |
| 398 |
{ |
| 399 |
if (componentChildren.Contains (childComponent)) |
| 400 |
return; |
| 401 |
|
| 402 |
componentChildren.Add (childComponent); |
| 403 |
AddVisibleEvent (childComponent); |
| 404 |
} |
| 405 |
|
| 406 |
protected void RemoveChildComponent (Component childComponent) |
| 407 |
{ |
| 408 |
if (!componentChildren.Contains (childComponent)) |
| 409 |
return; |
| 410 |
|
| 411 |
componentChildren.Remove (childComponent); |
| 412 |
RemoveVisibleEvent (childComponent); |
| 413 |
} |
| 414 |
|
| 415 |
protected virtual void AddVisibleEvent (Component component) |
| 416 |
{ |
| 417 |
SWF.Control control = null; |
| 418 |
|
| 419 |
if ((control = component as SWF.Control) != null) |
| 420 |
control.VisibleChanged += OnNotVisibleControlVisibleChanged; |
| 421 |
} |
| 422 |
|
| 423 |
protected virtual void RemoveVisibleEvent (Component component) |
| 424 |
{ |
| 425 |
SWF.Control control = null; |
| 426 |
|
| 427 |
if ((control = component as SWF.Control) != null) |
| 428 |
control.VisibleChanged -= OnNotVisibleControlVisibleChanged; |
| 429 |
} |
| 430 |
|
| 431 |
protected virtual bool IsComponentVisible (Component component) |
| 432 |
{ |
| 433 |
SWF.Control control = null; |
| 434 |
if ((control = component as SWF.Control) != null) |
| 435 |
return control.Visible; |
| 436 |
else // Component based providers will need to override this method |
| 437 |
return false; |
| 438 |
} |
| 439 |
|
| 374 |
#endregion |
440 |
#endregion |
|
|
441 |
|
| 442 |
#region Private Methods |
| 443 |
|
| 444 |
private void HandleComponentAdded (Component component, bool raiseEvent) |
| 445 |
{ |
| 446 |
AddChildComponent (component); |
| 447 |
|
| 448 |
// We don't add an invisible component but we keep track of its |
| 449 |
// Visible event to add it when Visible changes |
| 450 |
if (!IsComponentVisible (component)) |
| 451 |
return; |
| 452 |
|
| 453 |
InitializeComponentProvider (component, raiseEvent); |
| 454 |
} |
| 455 |
|
| 456 |
private void HandleComponentRemoved (Component component, bool raiseEvent) |
| 457 |
{ |
| 458 |
// We will only need to Terminate when is visible. |
| 459 |
if (IsComponentVisible (component)) |
| 460 |
TerminateComponentProvider (component, raiseEvent); |
| 461 |
|
| 462 |
RemoveChildComponent (component); |
| 463 |
} |
| 464 |
|
| 465 |
#endregion |
| 375 |
|
466 |
|
| 376 |
#region IRawElementProviderFragment Interface |
467 |
#region IRawElementProviderFragment Interface |
| 377 |
|
468 |
|