Introduction Thanks for being part of the Platte Canyon family as a subscriber to the EnterPage Newsletter. We are happy to announce our first iOS and Mac (Apple) applications, a new version of our ToolBook Storyboarder™ utility, and a new Windows and Mac Store application. We reflect on the changes related to writing software in the Mac environment, talk about the acquisition of SumTotal by Skillsoft, remind you about the LinkedIn ToolBook group, and then finish with Programming for e-Learning Developers tips on ToolBook. |
Platte Canyon's First iPhone/iPad/Mac Application: Music Genius™ We are excited to announce Platte Canyon's First iPhone/iPad/Mac Application: Music Genius™. This application joins its Windows Store and Windows Phone versions to give you a random set of 15 questions per category, which include years (1950's - 2010's), type of music (American Rock, Country, Pop, etc.), and specific groups (Beatles, Eagles, Led Zeppelin, and Van Halen). You can optionally store your information in order to compare your scores to others. There are over 4,500 questions. You are allowed 30 seconds per question. Since the Macintosh store does not have advertisements, that version if $2.99. The others are free. The iPhone/iPad version has an "in app" purchase option to remove advertisements for $2.99. If you have an iPhone, iPad, Mac, or Windows 8 device and you like music trivia, please download Music Genius. We'd appreciate any reviews and shares on social media as well! More Information Download on iTunes Download on the Mac Store |
Storyboarder™ Version 3 Exports ToolBook Fields/Record Fields to Matching TextBoxes in PowerPoint We released version 3 of the Platte Canyon® Storyboarder application yesterday. This innovative tool creates a Microsoft Word or PowerPoint storyboard document/presentation from an existing ToolBook book. New for version 3 is the ability to create individual text boxes in PowerPoint that match the content, size, location, font, and color of the corresponding fields or record fields in ToolBook. This makes Storyboarder a great tool for importing your content into other authoring tools that accept PowerPoint. Both the Word and PowerPoint exports include an optional screen capture of each page, field, button, and other text, question answers/feedback, simulation information, graphic placeholder file names, and other content. Storyboarder is available for ToolBook 11.5, 11, 10.5, and/or 10. There is a free evaluation version that works on books of up to five pages. More Information Order Storyboarder Evaluation Version |
Slide Show Soundtrack™ Now Available in the Windows and Mac Stores By Jeff Rhodes, Platte Canyon Multimedia Software Corporation Some of you might remember my "Programming for e-Learning Developers" preconference session at TBCON in 2010. In that session, we built a slide show application in both .NET and Flex. The application randomly displayed photos stored a subdirectory and played music stored in another subdirectory. We played a slide show at the conference reception that year and the program has come in handy at end-of-season sports banquets and similar events over the years. We collected a large number of pictures (including taking photos of newspaper articles and old snapshots) for my Dad's funeral reception and used the application for a self-running slide show that was quite memorable. When my younger son graduated from high school last spring, we got together with two other families to host a party. It wasn't optimal to put all the photos into one directory since each graduate might have a different number of pictures. Instead, I updated the application to switch between each directory, so that it would randomly grab a picture from graduate 1, then graduate 2, and finally graduate 3. We hooked laptops up to TV's both upstairs and downstairs and ran the shows for hours. Why all this explanation? After all the use of the app this year, I decided to try making it a Windows Store application. With naming help from my brother-in-law, Sean McHugh, Slide Show Soundtrack™ was born. And after completing Music Genius on the Macintosh, it seemed like a good vehicle for learning Apple's new Swift language as well. Slide Show Soundtrack has already been used by museums and other organizations. It is available for $2.99 using the links below. The Windows Store version has a 7-day trial version if you want to try it. More Information Windows Store Version Mac Store Version |
SumTotal Acquired by Skillsoft
As you may have heard, Skillsoft announced the acquisition of SumTotal Systems on August 21 and then completed the acquisition on October 1. There is no word yet on what this might mean for the future of ToolBook, but we are hopeful. Initial News Release News Release - Completion of Acquisition More Information from Skillsoft |
Join the ToolBook LinkedIn Group
As we mentioned in our last edition, the ToolBook List is likely on its last legs due to hardware issues and various providers blocking emails. We created the "Learning & Mastering ToolBook" group on LinkedIn and quite a number of you have joined. PG Software Development also has a ToolBook forum that is a good place to visit. We have included links for both groups below. Learning & Mastering ToolBook Support Group PG Software Tools ToolBook Forum |
Mac/Xcode/Objective-C Thoughts for a Longtime Windows/Visual Studio/Visual Basic User
By Jeff Rhodes, Platte Canyon Multimedia Software Corporation I used an Apple II in high school and then had a Mac when I ran the computer center at the Air Force Research Laboratory at Edwards Air Force Base in the early 1990's. But other than that and my iPhone, I have been on the Windows/Microsoft stack. However, creating iOS applications like Music Genius (described above) requires a Mac. Almost a year ago, I bought a MacBook Pro on Cyber Monday. Here are a few random observations on the journey.
|
Programming for e-Learning Developers Segment This feature is a short segment from Jeff's Programming for e-Learning Developers book. Handling a Click EventWe will cover ToolBook and Flash in this issue and finish with JavaScript and Silverlight in the next EnterPage issue.ToolBook – OpenScriptOpenScript® is the name of ToolBook’s internal programming or scripting language. It can be used for native CBT as well as for automation tools. OpenScript has one of the easiest syntaxes for handling events. Here is the syntax for a simple “buttonClick” handler.to handle buttonClick forward get ASYM_MessageBox("This is a test","Programming 101", "information", "OK") end buttonClick With OpenScript, unlike some of the other environments we’ll examine, the script editor does not provide a list of available events, though you can find the list in the online help. To designate that you are handling an event (as opposed to writing a function, which we will learn to do later), you use the to handle syntax. Next, we forward the message. A powerful feature of ToolBook is the concept of the message hierarchy, allowing messages to “bubble” to higher levels. After forwarding the message, we call a function or, more generically, a method, of the language. In this case, the function is ASYM_MessageBox. It has four parameters that we are using:
ToolBook – Actions EditorThe Actions Editor is a visual programming environment that is a front end for OpenScript when in author mode or when deploying that native .tbk and is a front end for JavaScript when your ToolBook book is exported to HTML. Once you open the Actions Editor for a particular object, it will pick a default event (on click in the case of a button). You can click on the event and see a list of all available events. Any events which have actions associated with them are shown in bold. Once you have selected the desired event, you then drag actions (methods using our terminology from the previous section) from the Actions Palette. There is only a single parameter for the Display alert method: the text to be shown in the message box.FlashFlash is actually the most complicated of the environments for handling events, though its approach is quite powerful as well. Beginning with ActionScript 3, Flash no longer allows script within objects but rather only in a layer, usually named the Actions layer for obvious reasons. You can insert a layer by right-clicking on the timeline and choosing Insert Layer. You would normally name it Actions and make it the top layer, but that is not required. I like to hide the layer to avoid putting objects on that layer. Again, nothing prevents that but most developers recommend keeping objects off the Actions layer. You then click on the desired frame and go to the Window menu – Actions (or press F9) to bring up the editor. The lowercase a in the frame indicates that there are actions in the layer.ActionScript uses the concept of the listener. In simple terms, a listener associates an event such as a button click with a method or event handler. This method must have the right signature, meaning that it must have the kind of parameters that the event generates. For example, a “key press” event will send parameters (also called arguments in this context) that tell the method what key was in fact pressed and whether the Ctrl, Alt, etc. keys were held down at the same time. The nice thing about listeners is that you can set up multiple functions that listen for a single event or one function that listens for multiple events. This can be quite handy, as we’ll see in some of the examples later in the book. The hard part to get your hands around is that you need to set up the listener relationship explicitly as shown below. runInitialLoad(); stop(); function runInitialLoad():void { // set up listener Button1.addEventListener(MouseEvent.CLICK, alertMessage); } function alertMessage(eventId:MouseEvent):void { DisplayText.text = "This is a test."; } We start by calling the runInitialLoad function. In Flash, a call like this that is not inside a function will be called as soon as the movie enters the frame. We use this function to set up the listener before anything else happens (in particular, before the user clicks the button). Note that lines like this end in a semicolon (;). I tend to use Flash like a page or form-based environment like ToolBook or Silverlight, but code like the stop(); line remind you that it is timeline-based. The stop line keeps us from moving to the next frame. The first thing to note is that Flash uses function for all methods. Any parameters to the function go between the parentheses. If there are no parameters, as in this case, you still need to include the parentheses. After that, you should specify the return type (though it is not required). A return type of void means that this function does not return anything. The reason I recommend specifying the return type is that the programming language will then let you know if you try to do something invalid. We’ll see more examples of this technique later in the book. At the end of the line is the left bracket { that shows the beginning of the function. This can go on the next line if desired but the most common syntax is to put it at the end of the line. Basically, any line without a bracket needs a semicolon instead. The next line is a comment (denoted by // in ActionScript) so that someone reading the code will understand what you are doing. Finally, we set up the actual listener. This is the typical way to call methods or set properties (covered in a later section) across languages. We call the addEventListener method of the Button1 object. The first parameter is the type of event you want to handle. You can type the first part (MouseEvent) and then the . to get a popup list of options. The events are shown in all capitals like CLICK. If you wanted a different event like RIGHT_CLICK, you could choose that instead. The second parameter is the name of the function that you want to call, alertMessage in this case. We then end the function with the right bracket }. This typically goes on its own line and is indented to match the indentation of the line with its matching left bracket. So in this case, it lines up with the word function. Finally, we have the alertMessage function. Since it is handling an event, its signature has to have an event object (of type MouseEvent) as the parameter. We again set the return type as void, meaning that the function doesn’t return a value. Since ActionScript 3 does not have an Alert component, we set the text of a field instead. Programming for e-Learning Developers Information Order Programming for e-Learning Developers ($29.95 with free shipping in the U.S.) |
Expert Information from Learning & Mastering ToolBook By Jeff Rhodes, Platte Canyon Multimedia Software Corporation TreeView ActiveX Question: Does anyone have any samples of how to use the TreeView ActiveX or similar controls that may be better? I have an Access database in my ToolBook application that I want to have cascading lists. Answer: We use the TList ActiveX control for our ToolBook Translation System product. Here are a couple of handlers that might help: to get addItemToTList string itemName, string strParentIndex, string itemTag system object ttst_s_tListID local itemNum local long parentIndex local string objectTypeLine -- add groupName if part of itemTag objectTypeLine = textline 2 of itemTag if objectTypeLine contains "_" AND "widget" is not in itemTag itemName = itemName && "(group " & quote & getGroupNameFromTag(word 1 of objectTypeLine) & quote & ")" end if -- second parameter must be null or of type long if isNumber(strParentIndex) parentIndex = strParentIndex get extAddItem(itemName, parentIndex) of ttst_s_tListID else get extAddItem(itemName) of ttst_s_tListID end if itemNum = extNewIndex of ttst_s_tListID if itemTag <> null extItemTag(itemNum) of ttst_s_tListID = itemTag end if return itemNum end addItemToTList -- this code is in the script for the TList control itself to handle checkForNewSelection system string ttst_s_itemTag local object tListID local string itemTag local long itemNum tListID = self itemNum = extListIndex of tListID if itemNum = -1 break end if itemTag = extItemTag(itemNum) of tListID if itemTag = null break end if get checkForUpdate() of currentPage of mainWindow ttst_s_itemTag = itemTag send ttst_LoadSelectedRecord end checkForNewSelection to handle extClick if target = self then send checkForNewSelection end forward end extClick Note that ToolBook itself used the TList for older versions of the Catalog and might use a version of it for the Book Explorer. So you can sniff through their code for examples as well. The user followed up with this response: Thanks for the starter, I have managed to get data into the TList control and extract the data selected by the user, but I want to use more of the options available in the ActiveX. I can retrieve the methods used in the control, but they don't equate to the help that is provided with the control. Usually they give VB examples and I'm not sure how to translate them to ToolBook, I have been using the trial and error message with a little bit of success, but it is a bit frustrating. I read an example of what I want to do on a VB forum giving the following example. Can anyone put me in the right direction to convert this to ToolBook. TList1.Grid.Cols = 2 TList1.Grid.ShowColTitles = true TList1.Grid.ShowRowTitles = true TList1.Grid.ColDefs(0).Width = 600 TList1.Grid.ColDefs(1).Width = 1200 TList1.Grid.ColDefs(1).CellDef Font.Bold = true TList1.Grid.ColDefs(1).CellDef Font.Size = 11 TList1.Grid.ColDefs(1).CellDef Font.Name = 'Arial' TList1.Grid.Cells(0,1). "Value" = 'Job No'Putting the data in from the database While Cells(i,1). Value = rsJonNo.Fields(JobNo)I wrote down the example so it may not be technically correct in the VB script. So far I have been using the script below to populate the control to handle buttonClick system dbconn,dbrecset,dbfields,@Code,@First,@Last,@Status local @Text mySQL = "SELECT AssetNo, LevelFLD, AssetLink FROM HierTBL Order by LevelFLD ASC"--WHERE LevelFLD = '1'" --'" & @Code & "'" send dbView(mysql) while NOT (extEOF of dbRecSet) if extitem[1] of dbfields = 0 get extAddItem(extitem[0] of dbfields) of tlist "test" else get extAddItem(extitem[2] of dbfields,extitem[1] of dbfields -1) of tlist "test" end get MoveNext() of dbrecset increment @Text end get extClose() of dbRecSet get extClose() of dbconn endAgain, any assistance would be appreciated. Jeff responded: It sounds like you are making good progress. Working with ActiveX controls is challenging as you have seen. The gist of the approach is to reverse the order and put "ext" on the front. So TList1.Grid.Cols = 2Would be: extCols of extGrid of tListId = 2 Since the Grid is a separate object, I like to put it in its own variable. That way you can look at in the debugger. If it has a number associated with it (something big like 11009832), then you are typically in good shape. So I would do something like this: local tListId local gridId tListId = TList "xyz" of this page gridId = extGrid of tListId extCols of gridId = 2 extShowColTitles of gridId = TRUE etc.The propertyList(), methodList() and eventList() OpenScript functions are real helpful. I like to combine them with sortList and listToTextline as shown below to give a nice display. Be sure to run this from the Command Window while in reader mode: put textlineToList(sortList(methodList(TList id 4 of Page id 11)))Here is the result: extAboutBox extAddItem extAddItem2 extAddItem2Ex extBeforeDrag extCheckRuntimeLicense extClear extCopyBuffer extDropTarget extFastAddItem extFastAddItemEx extFindItem extFindValue extFreeBuffer extGetItemByXY extGetItemRect extHitTest extIndexByBM extIsClipboardFormatAvailable extIsValidBM extIsValidBuffer extLoadBuffer extLoadData extOnDragDrop extOnDragOver extPasteBuffer extRefresh extRefreshItems extRemoveItem extSaveBuffer extSaveData extTranslateIndex extUpdateBackground extWebGoBack extWebGoForward extWebNavigateSimilarly for properties: put listToTextline(sortList(propertyList(TList id 4 of Page id 11))) allowAuthorActivate allowReaderActivate bounds ext_Dummy1 ext_Dummy2 ext_LcPresent extActiveGrid extAdd extAppearance extAutoExpand extAutoScrDuringDragDrop extBackColor extBackPicture extBackPictureAlignment extBackwardCompatibility extBorderStyle extBottomIndex extCaption extClearItem extClipboard extCoerceIndex extColDelimiter extConvertTabsToCols extCopyItem extCopyItemSub extCopyOne extCopySelected extCurrentIndexMethod extCurrentItem extCurrentItemBM extCurrentParent extDefItemCellAlignment extDefItemCellBackColor extDefItemCellBorderColor extDefItemCellBorderStyle extDefItemCellPictureAlignment extDefItemCellTextAlignment extDefMultiLine extDisableNoScroll extDragHighlight extDrawFocusRect extEnabled extEnvironment extExpand extExpandChildren extExpandEx extExpandNewItem extExplorerCompatible extFile extFixedSize extFont extFontBold extFontItalic extFontName extFontSize extFontStrikethru extFontUnderline extForeColor extFullPath extGradientColorFrom extGradientColorTo extGradientStyle extGrid extHasGrid extHasSubItems exthWnd extImage extImageStretch extIndent extInsert extInsertItem extInvBorderStyle extInvImage extInvStyle extIsClipboardAvailable extIsItemVisible extItemAlwaysHidden extItemBackColor extItemBM extItemCell extItemEditText extItemFontBold extItemFontItalic extItemFontName extItemFontSize extItemFontStrike extItemFontUnder extItemForeColor extItemGrid extItemHasGrid extItemHasValue extItemHeight extItemImageDefHeight extItemImageDefWidth extItemIntValue extItemLngValue extItemMark extItemMultiLine extItemNextSibling extItemParent extItemParentBM extItemPicValue extItemPMPicType extItemPrevSibling extItemSngValue extItemSorted extItemSortingKey extItemStrValue extItemTag extItemType extItemURL extItemValues extItemVirtualCount extItemVirtualParent extLevelDefs extList extListCount extListCountEx extListIndex extLoadAndAdd extLoadAndInsert extMarkedItemsAlwaysHidden extMarkHeight extMarkPicture extMarkTag extMarkWidth extMouseIcon extMousePointer extMSOutlineAdd extMultiSelect extNewIndex extNoIntegralHeight extNoPictureRoot extOLEDropMode extPathSeparator extPicInMultiLine extPictureClosed extPictureInverted extPictureLeaf extPictureList extPictureListCount extPictureMark extPictureMinus extPictureOpen extPicturePalette extPicturePlus extPictureRoot extPictureType extRedraw extSave extSaveOne extSaveSub extScrollbars extScrollHorz extSelBackColor extSelected extSelectEx extSelForeColor extSelItemCount extSelItemIndex extShift extShiftStep extShowCaption extShowChildren extShowHiddenItems extShowTitles extSmartDragDrop extTabStopDistance extText extTitleHeight extTitlePicture extTitleText extTitleVisible extTitleWidth extToolTipsBackColor extToolTipsForeColor extToolTipsMode extToolTipsViewStyle extTopIndex extTransparentBackground extTransparentBitmap extTransparentBitmapColor extTreeLinesColor extTreeLinesStyle extTriggerEvents extVersion extViewStyle extViewStyleEx extWebAutoNavigate extWebTargetFrame extWebURLBase extWidthOfText extWidthOfTextMin extXOffset hasPropertyDialog idNumber layer methods name notifyAfterMessages notifyBeforeMessages object parent position script sendToolbookMessages sharedScript size suspendMessages uniqueName userProperties visibleFinally for events: put listToTextline(sortList(eventList(TList id 4 of Page id 11))) ButtonClick ButtonDoubleClick ButtonDown ButtonUp extAfterEditing extClick extCollapse extDblClick extEditingKeyDown extEditingKeyPress extEditingKeyUp extExpand extGridCellClick extGridCellDblClick extHScroll extItemClick extItemDblClick extItemQueryData extKeyDown extKeyPress extKeyUp extMarkClick extMarkDblClick extMouseDown extMouseMove extMouseUp extOLEDragDrop extOLEDragOver extPictureClick extPictureDblClick extPlusMinusClick extPlusMinusDblClick extRequestEditing extVScroll KeyChar KeyDown KeyUp RightButtonDoubleClick RightButtonDown RightButtonUpUnfortunately, you can't use the same technique to find the properties, events, and methods of objects within the control like extGrid. In that case, you'll need to use the control documentation and experiment. Where possible, put each individual object into a variable so that you can see if you can create the reference to it correctly. |
OpenScript Tip from Learning & Mastering ToolBook
By Jeff Rhodes, Platte Canyon Multimedia Software Corporation Putting the Current Year in a ToolBook Field In our Learning & Mastering ToolBook training, we have a page that displays the "Starting Year." How do we make sure that this field has the current year in it rather than the year we wrote the training? We use the script below. notifyBefore enterPage local oldDateFormat oldDateFormat = sysDateFormat sysDateFormat = "y" text of self = sysDate sysDateFormat = oldDateFormat end enterPageWe handle the enterPage event using the notifyBefore syntax since the field does not receive that message on its own. We then create a local variable to hold the current sysDateFormat. We need that so we can set the sysDateFormat back when we are done. We then set the sysDateFormat to "y" so we get just the numeric year (such as 2014). We then set the text of self to be the sysDate. Finally, we set the sysDateFormat back. This is good practice in case other code (like our Progress Tracker in this case) is relying on sysDateFormat being a particular value. Notice that this code would have initialized a DHTML application to the year in which it was published. Not quite as good as updating it at runtime, but not too bad. |
Web Hint from Learning & Mastering ToolBook
By Denny Dedmore, SumTotal Systems, Inc. Universal Media Player Advanced Tab Question: If I use the Universal Media Player from the ToolBook Catalog to play an mp3 sound clip, will it play OK on platforms other than Windows? The application is DHTML & is exported for IE, Firefox, Chrome, iPad etc. The tutors are reporting that the students are simply copying & pasting the text out of my course modules into their assignments, which was predictable I suppose! If I disable a field in properties, it grays out the text. A long shot I suppose, but is there a way around this? Answer: On the ADVANCED Tab of the UMP you get to set which player will play the file. By default the UMP will use the Windows Media Player ActiveX control plugin for your browser to play it. This is a problem because the iPad does not support the Windows Media Player. Your best solution is to change the player (on the Advanced Tab) to QuickTime Player, which will play on iPad/iPhone, Safari (Windows and Mac), and IE and Firefox, and Chrome. |
The EnterPage is distributed up to four times per year. Individuals who have expressed interest in Platte Canyon Multimedia Software Corporation or its products receive The EnterPage. Suggestions for articles or proposals for article submissions are welcome. Send information to ep@plattecanyon.com. Back issues of the EnterPage are available at: http://www.plattecanyon.com/enterpage.aspx |
Platte Canyon Multimedia Software Corporation, 8870 Edgefield Drive, Colorado Springs, CO 80920, (719) 548-1110 |