Add acetate tools as a view overlay

The acetate tools allow you to display an overlay over views for markup purposes; this can enhance the collaboration experience by allowing each participant to see what the other participants are doing.

There are two built-in tools:

  • The cursor position tool displays an arrow indicating where a user's mouse is pointing.
  • The polyline tool displays a user's free-form drawings over a view.

By default, acetate tools are not mutually exclusive: you can display cursors and polyline drawings simultaneously in the same view, although this is customizable by setting the isMutuallyExclusive property.

This section describes how to add the default tools to your views.


Register the tool


AcetateToolset.registerToolDelegate() | HTML5
PWAcetateToolset.registerTool() | iOS
AcetateToolset.registerTool() | Android

Since you can have several acetate tools attached simultaneously to the same view within a client, you need a class for overseeing all tools, and that's the role of AcetateToolset. It is responsible for managing which tools are active in a view at any given time, and for broadcasting to the view the event raised in the acetate.

In order for this to work, you must first register your tool with the toolset. The method for this is registerTool (called registerToolDelegate in the HTML5 API).

Because the acetate tool can only be added after a client connects, the tool registration is usually done within a handler for the connection event, or the method that creates the view.

In the snippets below, we register a polyline tool with the toolset.


var MyToolset = new pureweb.client.collaboration.AcetateToolset();
var MyPolylineToolDelegate = new pureweb.client.collaboration.PolylineTool();
var MyPolylineTool = MyToolset.registerToolDelegate(MyPolylineToolDelegate);

iOS (Obj-C)

self.myToolset = [[PWAcetateToolset alloc] init];
PWPolylineTool *myPolylineTool = [[PWPolylineTool alloc] init];
[self.myToolset registerTool:myPolylineTool];


AcetateToolset myToolset = new AcetateToolset();
PolylineTool myPolylineTool = new PolylineTool();

Attach the toolset to a view


View.setAcetateToolset() | HTML5 | Android
PWView.acetateToolset() | iOS

Once the tool is registered with a toolset, the next step is to associate this toolset with a particular view. This is a single line of code, and all you need to know is the view's name.

In the example below, we associate MyToolset with a view called MyAwesomeView.



iOS (Obj-C)

MyAwesomeView.acetateToolset = self.myToolset;



Activate the tool


AcetateToolset.activateTool() | HTML5 | Android
PWAcetateToolset.activateTool() | iOS

Activating an acetate tool is not the same as launching it. The activation step only makes the tool available, so that markup can be shown later.

In the example below, we activate our polyline tool for the toolset that we added earlier.



iOS (Obj-C)

[self.myToolset activateTool:myPolylineTool];



Set the acetate's visibility


CollaborationManager.setMarkupVisible() | HTML5 | Android
PWCollaborationManager.setMarkupVisible() | iOS

Once an acetate tool is registered and activated, you can enable it by making the acetate layer visible. A common approach is to create a user interface element for toggling acetate on and off.

Note that making acetate visible in a client has the following effects:

  • displays the user's acetate layer (cursor and/or markups) to all other participants,
  • shows to the user the other participants' acetate layer, but only for those who have toggled on the acetate in their own client.
  In some cases, you may want to suppress the transmission of input events to the view while the user is interacting with the acetate layer. See Suppress input transmission.

To make a tool visible, you set the value for setMarkupVisible to true, providing the user's session ID as a parameter.


var collaborationManager = pureweb.getFramework().getCollaborationManager();
var localSession = pureweb.getFramework().getClient().getSessionId();
collaborationManager.setMarkupVisible(localSession, true);

iOS (Obj-C)

[[[PWFramework.sharedInstance] collaborationManager] setMarkupVisible:sessionId markupVisible:YES];


framework.getCollaborationManager().setMarkupVisible(sessionId, true);

Clear the markup


ClearMarkupTool | HTML5 | Android
PWClearMarkupTool | iOS

CollaborationManager | HTML5 | Android
PWCollaborationManager | iOS

When a user toggles the acetate visibility off, this does not clear the markups, it only hides them from view. To clear the markups, you would use the ClearMarkupTool class, or one of the methods provided for this purpose in the CollaborationManager class, such as:

  • removeAcetateMarkupByTools
  • removeAcetateMarkupByInstance
  • removeAcetateMarkupByType
  • removeAcetateMarkupBySession
  • removeAllAcetateMarkupBySession


Putting it all together

The code below illustrates the common workflow of implementing an acetate tool in a client. There are three main steps to this workflow:

  • Define a function that adds the tool to the client.
  • Create an interface element that provides the user with a means to toggle the tool.
  • Define the function that will display or hide the tool when the user interacts with the interface element.


// Add a handler for the connection event.
// The acetate tool will be added to the client once the client connects.
pureweb.listen(pureweb.getClient(), pureweb.client.WebClient.EventType.CONNECTED_CHANGED, onConnectedChanged);

// Define the handling function so that it adds the tool when the user connects
function onConnectedChanged(e) {
    var toolset = new pureweb.client.collaboration.AcetateToolset();
    var polylineToolDelegate = new pureweb.client.collaboration.PolylineTool();
    var polylineTool = toolset.registerToolDelegage(polylineToolDelegate);


// Create an interface element for toggling acetate on and off
var visChkBox =  doc.createElement('input');
visChkBox.setAttribute('type', 'checkbox');
visChkBox.setAttribute('sessionId', sessionId);
visChkBox.setAttribute('style', 'goog-checkbox; margin-left: 5px;');
visChkBox.setAttribute('margin-left', '5px');
if (collaborationMgr.getMarkupVisible(sessionId) === true) {
    visChkBox.checked = true;
} else {
    visChkBox.checked = false;
visChkBox.onclick = ddxclient.onAcetateVisibilityClicked_;
// Define the checkbox's onclick function to set the acetate visibility
MyView.onAcetateVisibilityClicked_ = function(e) {
    var sessionId ='sessionId');

iOS (Obj-C)

This example assumes that you created an element in the UI to handle activating the acetate layer, and that this element will call the "enabledDidChange" function whenever the end user selects or unselects it..

@synthesize toolset = _toolset;

// The function to load the acetate tools will be called once the view is loaded
- (void)viewDidLoad
    [self loadAcetateTools];
    view.acetateToolset = self.toolset;

// The function that actually loads the acetate, to make it available
- (void)loadAcetateTools
    self.toolset = [[PWAcetateToolset alloc] init];
    PWPolylineTool *polylineTool = [[PWPolylineTool alloc] init];
    [self.toolset registerTool:polylineTool];
    [self.toolset activateTool:polylineTool];

// The function that gets called when the user 
// chooses to enable acetate from the UI											
- (void)enabledDidChange:(PWGuid *)sessionId
    PWCollaborationManager *collaborationManager = [[PWFramework sharedInstance] collaborationManager];
    BOOL enabled = ![collaborationManager getMarkupVisible: sessionId];
    MyAwesomeView.inputTransmissionEnabled = enabled;
    [collaborationManager setMarkupVisible: sessionId markupVisible: enabled];