Pages: 1
Print
Author Topic: Add new button to toolbar  (Read 3987 times)
biswajitsr
Member

Posts: 44


« on: July 27, 2010, 02:28:07 AM »

In XMetaL author how to add toolbar button. If it is possible then can anyone please give some sample code. Thanks in advance.
Logged
Derek Read
Program Manager (XMetaL)
Administrator
Member

Posts: 2621



WWW
« Reply #1 on: July 27, 2010, 03:04:32 PM »

Users are free to make their own manual changes, so you'll probably want to start with the XMetaL Author help for information on these types of toolbar changes, starting with the main topic "Customizing the user interface" to familiarize yourself with what can be done there. That also means any scripts you write should not assume an out of the box installation as toolbars or buttons may have been deleted, moved around, added, etc.

As a developer this feature allows you to reset the toolbars on your test machine if your script has messed them up. To do that right click in the toolbar area, select "Customize", then in the dialog that appears select the toolbar (or menu) your script messed up and click the "Reset" button.

Before you begin scripting toolbar and menu changes a good topic to read in the Programmers Guide is this one: "Command Bar interfaces". If you are familiar with customizing MS Word toolbars and menus with script then you will see that our APIs for this are very similar.

Here's a sample of a basic function that will add a new button to an existing toolbar. Most of the time you will want to place such script into the event macro called On_Default_CommandBars_Complete.

Code:
//JSCRIPT:
function addButtonToToolbar(strToolbarName,strOnAction,strDescriptionText,strTooltipText,intFaceId,boolBeginGroup) {
var tbr = Application.CommandBars.item(strToolbarName);
var boolButtonExists = false;

for (i=1;i<=tbr.Controls.count;i++) {
if (tbr.Controls.item(i).OnAction == strOnAction) {
boolButtonExists = true;
}
}

if (!boolButtonExists) {
var newButton = tbr.Controls.Add(1);
newButton.DescriptionText = strDescriptionText;
newButton.OnAction        = strOnAction;
newButton.TooltipText     = strTooltipText;
newButton.BeginGroup      = boolBeginGroup;
newButton.FaceId          = intFaceId;
}
}
var faceId = Application.MakeFaceId("Misc 1 (Custom)",5,2);
addButtonToToolbar("Standard","My Macro Name","Hello World","My Tooltip",faceId,false);

Notice that the code checks to see that the button does not already exist. If you do not do this you will end up with duplicate buttons (one for each time the event fires).

For information on any of the methods or properties above refer to the Programmer's Guide.

You can probably use this function as it is (test it first), but at a minimum you will probably need to read the help topic for the "MakeFaceId" property so you understand how toolbar icons (face ids) are referenced. In this example I've externalized the call to MakeFaceId. You could obviously put it into any function you end up writing if you feel that might be cleaner.
« Last Edit: July 27, 2010, 03:22:06 PM by Derek Read » Logged
dcramer
Member

Posts: 120


« Reply #2 on: July 28, 2010, 02:35:25 PM »

I'd started on some xslts to generate the add/remove toolbar changes a while back. I believe I had it working for the menus but hadn't added the toolbars yet. The idea is to set up your menus manually using the XMetaL GUI, then close XMetaL so it saves all that to a tbr file. Then you run this over your tbr file and it gives you the js you need to add to your mcr file. Why do this? Long ago I thought the right way to do it was to use xmetal to create the tbr file and push stuff out that way. Rather than manually code all the menu changes (I have a bunch) I figured I'd write an xslt (note this is an xslt 2.0 stylesheet, so you should use Saxon 9):

Code:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

  <xsl:output method="text"/>

  <xsl:param name="backslash">\</xsl:param>
 
  <xsl:template match="/">
// Get the CommandBars object
var cmdBars = Application.CommandBars;
// Get a single command bar (the main menu bar)
var menuBar = cmdBars.item("Menu bar");
// Get all of the menu bar's controls (all of the menus)
var menuBarCtrls = menuBar.Controls;

var currentTopMenu;
var currentTopMenuCtrls;
<xsl:apply-templates select="//CommandBar[./Name = 'Menu bar']/Controls/PopupMenu"/>
  </xsl:template>
 
<xsl:template match="text()"/>

<xsl:param name="quote">['"]</xsl:param>
<xsl:param name="squote">'</xsl:param>

  <xsl:template match="PopupMenu[./BuiltIn]">
currentTopMenu = menuBarCtrls.item(<xsl:value-of select="count(preceding-sibling::*) + 1"/>);
currentTopMenuCtrls = currentTopMenu.Controls;
<xsl:apply-templates select="MenuControls"/>
  </xsl:template>

  <xsl:template match="MenuControls[parent::PopupMenu[not(./BuiltIn)]]">
<xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="PopupMenuItem[not(./BuiltIn) and ancestor::PopupMenu[./BuiltIn]]">
<xsl:param name="menu">currentTop</xsl:param>
for (i=1;i&lt;=<xsl:value-of select="$menu"/>MenuCtrls.count; i++) {
if(<xsl:value-of select="$menu"/>MenuCtrls.item(i).Caption == '<xsl:value-of select="replace(./Caption,$quote,concat($backslash,$backslash,$squote))"/>'){ <xsl:value-of select="$menu"/>MenuCtrls.item(i).Delete(); }
}
newSubItem = <xsl:value-of select="$menu"/>MenuCtrls.Add(5,1,<xsl:value-of select="count(preceding-sibling::*) + 1"/>);
newSubItem.Caption = "<xsl:value-of select="replace(./Caption,$quote,concat($backslash,$backslash,$squote))"/>";
newSubItem.BeginGroup = <xsl:value-of select="./BeginGroup"/>;
newSubItem.OnAction = "<xsl:value-of select="./OnAction"/>";
newSubItem.Enabled = true;
  </xsl:template>


  <xsl:template match="PopupSubMenu[not(./BuiltIn) and ancestor::PopupMenu[./BuiltIn] ]">
<xsl:param name="menu">currentTop</xsl:param>
for (i=1;i&lt;=<xsl:value-of select="$menu"/>MenuCtrls.count; i++) {
if(<xsl:value-of select="$menu"/>MenuCtrls.item(i).Caption == '<xsl:value-of select="replace(./Caption,$quote,concat($backslash,$backslash,$squote))"/>'){ <xsl:value-of select="$menu"/>MenuCtrls.item(i).Delete(); }
}
newSubItem = <xsl:value-of select="$menu"/>MenuCtrls.Add(5,1,<xsl:value-of select="count(preceding-sibling::*) + 1"/>);
newSubItem.Caption = '<xsl:value-of select="./Caption"/>';

newSubItem.BeginGroup = <xsl:value-of select="./BeginGroup"/>;
newSubItem.OnAction = "<xsl:value-of select="./OnAction"/>";
newSubItemMenuCtrls = newSubItem.Controls;
<xsl:apply-templates>
  <xsl:with-param name="menu">newSubItem</xsl:with-param>
</xsl:apply-templates>

  </xsl:template>


</xsl:stylesheet>
Logged

David Cramer
Technical Writer
Motive, an Alcatel-Lucent Company
Pages: 1
Print
Jump to:  

email us