Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials - Web Development

1802 Articles
article-image-getting-started-couchdb-and-futon
Packt
27 Nov 2012
11 min read
Save for later

Getting Started with CouchDB and Futon

Packt
27 Nov 2012
11 min read
(For more resources related to this topic, see here.) What is CouchDB? The first sentence of CouchDB's definition (as defined by http://couchdb.apache.org/) is as follows: CouchDB is a document database server, accessible through the RESTful JSON API. Let's dissect this sentence to fully understand what it means. Let's start with the term database server. Database server CouchDB employs a document-oriented database management system that serves a flat collection of documents with no schema, grouping, or hierarchy. This is a concept that NoSQL has introduced, and is a big departure from relational databases (such as MySQL), where you would expect to see tables, relationships, and foreign keys. Every developer has experienced a project where they have had to force a relational database schema into a project that really didn't require the rigidity of tables and complex relationships. This is where CouchDB does things differently; it stores all of the data in a self-contained object with no set schema. The following diagram will help to illustrate this: In order to handle the ability for many users to belong to one-to-many groups in a relational database (such as MySQL), we would create a users table, a groups table, and a link table, called users_groups. This practice is common to most web applications. Now look at the CouchDB documents. There are no tables or link tables, just documents. These documents contain all of the data pertaining to a single object. This diagram is very simplified. If we wanted to create more logic around the groups in CouchDB, we would have had to create group documents, with a simple relationship between the user documents and group documents. Let's dig into what documents are and how CouchDB uses them. Documents To illustrate how you might use documents, first imagine that you are physically filling out the paper form of a job application. This form has information about you, your address, and past addresses. It also has information about many of your past jobs, education, certifications, and much more. A document would save all of this data exactly in the way you would see it in the physical form - all in one place, without any unnecessary complexity. In CouchDB, documents are stored as JSON objects that contain key and value pairs. Each document has reserved fields for metadata such as id, revision, and deleted. Besides the reserved fields, documents are 100 percent schema-less, meaning that each document can be formatted and treated independently with as many different variations as you might need. Example of a CouchDB document Let's take a look at an example of what a CouchDB document might look like for a blog post: { "_id": "431f956fa44b3629ba924eab05000553", "_rev": "1-c46916a8efe63fb8fec6d097007bd1c6", "title": "Why I like Chicken", "author": "Tim Juravich", "tags": [ "Chicken", "Grilled", "Tasty" ], "body": "I like chicken, especially when it's grilled." } Downloading the example code You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you. JSON format The first thing you might notice is the strange markup of the document, which is JavaScript Object Notation (JSON). JSON is a lightweight data-interchange format based on JavaScript syntax and is extremely portable. CouchDB uses JSON for all communication with it. Key-value storage The next thing that you might notice is that there is a lot of information in this document. There are key-value pairs that are simple to understand, such as "title", "author", and "body", but you'll also notice that "tags" is an array of strings. CouchDB lets you embed as much information as you want directly into a document. This is a concept that might be new to relational database users who are used to normalized and structured databases. Reserved fields Let's look at the two reserved fields: _id and _rev. _id is the unique identifier of the document. This means that _id is mandatory, and no two documents can have the same value. If you don't define an _id on creation of a document, CouchDB will choose a unique one for you. _rev is the revision version of the document and is the field that helps drive CouchDB's version control system. Each time you save a document, the revision number is required so that CouchDB knows which version of the document is the newest. This is required because CouchDB does not use a locking mechanism, meaning that if two people are updating a document at the same time, then the first one to save his/her changes first, wins. One of the unique things about CouchDB's revision system is that each time a document is saved, the original document is not overwritten, and a new document is created with the new data, while CouchDB stores a backup of the previous documents in its original form in an archive. Old revisions remain available until the database is compacted, or some cleanup action occurs. The last piece of the definition sentence is the RESTful JSON API. So, let's cover that next. RESTful JSON API In order to understand REST, let's first define HyperText Transfer Protocol (HTTP ). HTTP is the underlying protocol of the Internet that defines how messages are formatted and transmitted and how services should respond when using a variety of methods. These methods consist of four main verbs, such as GET, PUT, POST, and DELETE. In order to fully understand how HTTP methods function, let's first define REST. Representation State Transfer (REST ) is a stateless protocol that accesses addressable resources through HTTP methods. Stateless means that each request contains all of the information necessary to completely understand and use the data in the request, and addressable resources means that you can access the object via a URL. That might not mean a lot in itself, but, by putting all of these ideas together, it becomes a powerful concept. Let's illustrate the power of REST by looking at two examples: Resource GET PUT POST DELETE http://localhost/collection Read a list of all of the items inside of collection Update the Collection with another collection Create a new collection Delete the collection http://localhost/collection/abc123 Read the details of the abc123 item inside of collection Update the details of abc123 inside of collection Create a new object abc123 inside of a collection Delete abc123 from collection By looking at the table, you can see that each resource is in the form of a URL. The first resource is collection, and the second resource is abc123, which lives inside of collection. Each of these resources responds differently when you pass different methods to them. This is the beauty of REST and HTTP working together. Notice the bold words I used in the table: Read, Update, Create, and Delete. These words are actually, in themselves, another concept, and it, of course, has its own term; CRUD. The unflattering term CRUD stands for Create, Read, Update, and Delete and is a concept that REST uses to define what happens to a defined resource when an HTTP method is combined with a resource in the form of a URL. So, if you were to boil all of this down, you would come to the following diagram: This diagram means: In order to CREATE a resource, you can use either the POST or PUT method In order READ a resource, you need to use the GET method In order to UPDATE a resource, you need to use the PUT method In order to DELETE a resource, you need to use the DELETE method As you can see, this concept of CRUD makes it really clear to find out what method you need to use when you want to perform a specific action. Now that we've looked at what REST means, let's move onto the term API , which means Application Programming Interface. While there are a lot of different use cases and concepts of APIs, an API is what we'll use to programmatically interact with CouchDB. Now that we have defined all of the terms, the RESTful JSON API could be defined as follows: we have the ability to interact with CouchDB by issuing an HTTP request to the CouchDB API with a defined resource, HTTP method, and any additional data. Combining all of these things means that we are using REST. After CouchDB processes our REST request, it will return with a JSON-formatted response with the result of the request. All of this background knowledge will start to make sense as we play with CouchDB's RESTful JSON API, by going through each of the HTTP methods, one at a time. We will use curl to explore each of the HTTP methods by issuing raw HTTP requests. Time for action – getting a list of all databases in CouchDB Let's issue a GET request to access CouchDB and get a list of all of the databases on the server. Run the following command in Terminal curl -X GET http://localhost:5984/_all_dbs Terminal will respond with the following: ["_users"] What just happened? We used Terminal to trigger a GET request to CouchDB's RESTful JSON API. We used one of the options: -X, of curl, to define the HTTP method. In this instance, we used GET. GET is the default method, so technically you could omit -X if you wanted to. Once CouchDB processes the request, it sends back a list of the databases that are in the CouchDB server. Currently, there is only the _users database, which is a default database that CouchDB uses to authenticate users. Time for action – creating new databases in CouchDB In this exercise, we'll issue a PUT request , which will create a new database in CouchDB. Create a new database by running the following command in Terminal: curl -X PUT http://localhost:5984/test-db Terminal will respond with the following: {"ok":true} Try creating another database with the same name by running the following command in Terminal: curl -X PUT http://localhost:5984/test-db Terminal will respond with the following: {"error":"file_exists","reason":"The database could not becreated, the file already exists."} Okay, that didn't work. So let's to try to create a database with a different name by running the following command in Terminal: curl -X PUT http://localhost:5984/another-db Terminal will respond with the following: {"ok":true} Let's check the details of the test-db database quickly and see more detailed information about it. To do that, run the following command in Terminal: curl -X GET http://localhost:5984/test-db Terminal will respond with something similar to this (I re-formatted mine for readability): {"committed_update_seq": 1,"compact_running": false,"db_name": "test-db","disk_format_version": 5,"disk_size": 4182,"doc_count": 0,"doc_del_count": 0,"instance_start_time": "1308863484343052","purge_seq": 0,"update_seq": 1} What just happened? We just used Terminal to trigger a PUT method to the created databases through CouchDB's RESTful JSON API, by passing test-db as the name of the database that we wanted to create at the end of the CouchDB root URL. When the database was successfully created, we received a message that everything went okay. Next, we created a PUT request to create another database with the same name test-db. Because there can't be more than one database with the same name, we received an error message We then used a PUT request to create a new database again, named another-db. When the database was successfully created, we received a message that everything went okay. Finally, we issued a GET request to our test-db database to find out more information on the database. It's not important to know exactly what each of these statistics mean, but it's a useful way to get an overview of a database. It's worth noting that the URL that was called in the final GET request was the same URL we called when we first created the database. The only difference is that we changed the HTTP method from PUT to GET. This is REST in action!
Read more
  • 0
  • 0
  • 5136

article-image-web-services-testing-and-soapui
Packt
16 Nov 2012
8 min read
Save for later

Web Services Testing and soapUI

Packt
16 Nov 2012
8 min read
(For more resources related to this topic, see here.) SOA and web services SOA is a distinct approach for separating concerns and building business solutions utilizing loosely coupled and reusable components. SOA is no longer a nice-to-have feature for most of the enterprises and it is widely used in organizations to achieve a lot of strategic advantages. By adopting SOA, organizations can enable their business applications to quickly and efficiently respond to business, process, and integration changes which usually occur in any enterprise environment. Service-oriented solutions If a software system is built by following the principles associated with SOA, it can be considered as a service-oriented solution. Organizations generally tend to build service-oriented solutions in order to leverage flexibility in their businesses, merge or acquire new businesses, and achieve competitive advantages. To understand the use and purpose of SOA and service-oriented solutions, let's have a look at a simplified case study. Case study Smith and Co. is a large motor insurance policy provider located in North America. The company uses a software system to perform all their operations which are associated with insurance claim processing. The system consists of various modules including the following: Customer enrollment and registration Insurance policy processing Insurance claim processing Customer management Accounting Service providers management With the enormous success and client satisfaction of the insurance claims processed by the company during the recent past, Smith and Co. has acquired InsurePlus Inc., one of its competing insurance providers, a few months back. InsurePlus has also provided some of the insurance motor claim policies which are similar to those that Smith and Co. provides to their clients. Therefore, the company management has decided to integrate the insurance claim processing systems used by both companies and deliver one solution to their clients. Smith and Co. uses a lot of Microsoft(TM) technologies and all of their software applications, including the overall insurance policy management system, are built on .NET framework. On the other hand, InsurePlus uses J2EE heavily, and their insurance processing applications are all based on Java technologies. To worsen the problem of integration, InsurePlus consists of a legacy customer management application component as well, which runs on an AS-400 system. The IT departments of both companies faced numerous difficulties when they tried to integrate the software applications in Smith and Co. and InsurePlus Inc. They had to write a lot of adapter modules so that both applications would communicate with each other and do the protocol conversions as needed. In order to overcome these and future integration issues, the IT management of Smith and Co. decided to adopt SOA into their business application development methodology and convert the insurance processing system into a service-oriented solution. As the first step, a lot of wrapper services (web services which encapsulate the logic of different insurance processing modules) were built, exposing them as web services. Therefore the individual modules were able to communicate with each other with minimum integration concerns. By adopting SOA, their applications used a common language, XML, in message transmission and hence a heterogeneous systems such as the .NET based insurance policy handling system in Smith and Co. was able to communicate with the Java based applications running on InsurePlus Inc. By implementing a service-oriented solution, the system at Smith and Co. was able to merge with a lot of other legacy systems with minimum integration overhead. Building blocks of SOA When studying typical service-oriented solutions, we can identify three major building blocks as follows: Web services Mediation Composition Web services Web services are the individual units of business logic in SOA. Web services communicate with each other and other programs or applications by sending messages. Web services consist of a public interface definition which is a central piece of information that assigns the service an identity and enables its invocation. The service container is the SOA middleware component where the web service is hosted for the consuming applications to interact with it. It allows developers to build, deploy, and manage web services and it also represents the server-side processor role in web service frameworks. A list of commonly used web service frameworks can be found at http://en.wikipedia.org/wiki/List_of_web_service_frameworks; here you can find some popular web service middleware such as Windows Communication Foundation (WCF) Apache CXF, Apache Axis2, and so on. Apache Axis2 can be found at http://axis.apache.org/ The service container contains the business logic, which interacts with the service consumer via a service interface. This is shown in the following diagram: Mediation Usually, the message transmission between nodes in a service-oriented solution does not just occur via the typical point-to-point channels. Instead, once a message is received, it can be flowed through multiple intermediaries and subjected to various transformation and conversions as necessary. This behavior is commonly referred to as message mediation and is another important building block in service-oriented solutions. Similar to how the service container is used as the hosting platform for web services, a broker is the corresponding SOA middleware component for message mediation. Usually, enterprise service bus (ESB) acts as a broker in service-oriented solutions Composition In service-oriented solutions, we cannot expect individual web services running alone to provide the desired business functionality. Instead, multiple web services work together and participate in various service compositions. Usually, the web services are pulled together dynamically at the runtime based on the rules specified in business process definitions. The management or coordination of these business processes are governed by the process coordinator, which is the SOA middleware component associated with web service compositions. Simple Object Access Protocol Simple Object Access Protocol (SOAP) can be considered as the foremost messaging standard for use with web services. It is defined by the World Wide Web Consortium (W3C) at http://www.w3.org/TR/2000/NOTE-SOAP-20000508/ as follows: SOAP is a lightweight protocol for exchange of information in a decentralized, distributed environment. It is an XML based protocol that consists of three parts: an envelope that defines a framework for describing what is in a message and how to process it, a set of encoding rules for expressing instances of application-defined datatypes, and a convention for representing remote procedure calls and responses. The SOAP specification has been universally accepted as the standard transport protocol for messages processed by web services. There are two different versions of SOAP specification and both of them are widely used in service-oriented solutions. These two versions are SOAP v1.1 and SOAP v1.2. Regardless of the SOAP specification version, the message format of a SOAP message still remains intact. A SOAP message is an XML document that consists of a mandatory SOAP envelope, an optional SOAP header, and a mandatory SOAP body. The structure of a SOAP message is shown in the following diagram: The SOAP Envelope is the wrapper element which holds all child nodes inside a SOAP message. The SOAP Header element is an optional block where the meta information is stored. Using the headers, SOAP messages are capable of containing different types of supplemental information related to the delivery and processing of messages. This indirectly provides the statelessness for web services as by maintaining SOAP headers, services do not necessarily need to store message-specific logic. Typically, SOAP headers can include the following: Message processing instructions Security policy metadata Addressing information Message correlation data Reliable messaging metadata The SOAP body is the element where the actual message contents are hosted. These contents of the body are usually referred to as the message payload. Let's have a look at a sample SOAP message and relate the preceding concepts through the following diagram: In this example SOAP message, we can clearly identify the three elements; envelope, body, and header. The header element includes a set of child elements such as <wsa:To>, <wsa:ReplyTo>, <wsa:Address>, <wsa:MessageID>, and <wsa:Action>. These header blocks are part of the WS-Addressing specification. Similarly, any header element associated with WS-* specifications can be included inside the SOAP header element. The <s:Body> element carries the actual message payload. In this example, it is the <p:echoString> element with a one child element. When working with SOAP messages, identification of the version of SOAP message is one of the important requirements. At first glance, you can determine the version of the specification used in the SOAP message through the namespace identifier of the <Envelope> element. If the message conforms to SOAP 1.1 specification, it would be http://schemas.xmlsoap.org/soap/envelope/, otherwise http://www.w3.org/2003/05/soap-envelope is the name space identifier of SOAP 1.2 messages. Alternatives to SOAP Though SOAP is considered as the standard protocol for web services communication, it is not the only possible transport protocol which is used. SOAP was designed to be extensible so that the other standards could be integrated into it. The WS-* extensions such as WS-Security, WS-Addressing, and WSReliableMessaging are associated with SOAP messaging due to this extensible nature. In addition to the platform and language agnosticism, SOAP messages can be transmitted over various transports such as HTTP, HTTPS, JMS, and SMTP among others. However, there are a few drawbacks associated with SOAP messaging. The performance degradations due to heavy XML processing and the complexities associated with the usage of various WS-* specifications are two of the most common disadvantages of the SOAP messaging model. Because of these concerns, we can identify some alternative approaches to SOAP.
Read more
  • 0
  • 0
  • 3015

article-image-graphic-design-working-clip-art-and-making-your-own
Packt
09 Nov 2012
9 min read
Save for later

Graphic Design - Working with Clip Art and Making Your Own

Packt
09 Nov 2012
9 min read
(For more resources related to this topic, see here.) Making symbols from Character Palette into clip art—where to find clip art for iWork Clip art is the collective name for predrawn images, pictures, and symbols that can be quickly added to documents. In standalone products, a separate Clip art folder is often added to the package. iWork doesn't have one — this has been the subject of numerous complaints on the Internet forums. However, even though there is no clip art folder as such in iWork, there are hundreds of clip-art images on Mac computers that come as part of our computers. Unlike MS Office or Open Office that are separate Universes on your machine, iWork (even though we buy it separately) is an integral part of the Mac. It complements and works with applications that are already there, such as iLife (iPhoto), Mail, Preview, Address Book, Dictionaries, and Spotlight. Getting ready So, where is the clip art for iWork? First, elements of the Pages templates can be used as clip art—just copy and paste them. Look at this wrought iron fence post from the Collector Newsletter template. It is used there as a column divider. Select and copy-paste it into your project, set the image placement to Floating, and move it in between the columns or text boxes. The Collector Newsletter template also has a paper clip, a price tag, and several images of slightly rumpled and yellowed sheets of paper that can be used as backgrounds. Images with little grey houses and house keys from the Real Estate Newsletter template are good to use with any project related to property. The index card image from the Back Page of the Green Grocery Newsletter template can be used for designing a cooking recipe, and the background image of a yellowing piece of paper from the Musical Concert poster would make a good background for an article on history. Clip art in many templates is editable and easy to resize or modify. Some of the images are locked or grouped. Under the Arrange menu, select the Unlock and Ungroup options, to use those images as separate graphic elements. Many of the clip-art images are easy to recreate with iWork tools. Bear in mind, however, that some of the images have low resolution and should only be used with small dimensions. You will find various clip-art images in the following locations: A dozen or so attractive clip-art images are in Image Bullets, under the Bullets drop-down menu: Open the Text Inspector, click on the List tab, and choose Image Bullets from the Bullets & Numbering drop-down menu. There, you will find checkboxes and other images. Silver and gold pearls look very attractive, but any of your own original images can also be made into bullets. In Bullets, choose Custom Image | Choose and import your own image. Note that images with shadows may distort the surrounding text. Use them with care or avoid applying shadows. Navigate to Macintosh HD | Library | Desktop Pictures: Double-click on the hard disk icon on your desktop and go to Library | Desktop Pictures. There are several dozen images including the dew drop and the lady bug. These are large files, good enough for using as background images. They are not, strictly speaking, clip art but are worth keeping in mind. Navigate to Home| Pictures | iChat Icons (or HD | Library | Application Support | Apple | iChat Icons): The Home folder icon (a little house) is available in the side panel of any folder on your Mac. This is where documents associated with your account are stored on your computer. It has a Pictures folder with a dozen very small images sitting in the folder called iChat Icons. National flags are stored here as button-like images. The apple image can be found in the Fruit folder. The gems icons, such as the ruby heart, from this folder look attractive as bullets. Navigate to HD | Library | User Pictures: You can find animals, flowers, nature, sports, and other clip-art images in this folder. These are small TIFF files that can be used as icons when a personal account is set up on a Mac. But of course, they can be used as clip art. The Sports folder has a selection of balls, but not a cricket ball, even though cricket may have the biggest following in the world (Britain, South Africa, Australia, India, Pakistan, Bangladesh, Sri Lanka, and many Caribbean countries). But, a free image of the cricket ball from Wikipedia/Wikimedia can easily be made into clip art. There may be several Libraries on your Mac. The main Library is on your hard drive; don't move or rename any folders here. Duplicate images from this folder and use copies. Your personal library (it is created for each account on your machine) is in the Home folder. This may sound a bit confusing, but you don't have to wade through endless folders to find what you want, just use Spotlight to find relevant images on your computer, in the same way that you would use Google to search on the Internet. Character Palette has hundreds of very useful clip-art-like characters and symbols. You can find the Character Palette via Edit | Special Characters. Alternatively, open System Preferences | International | Input Menu. Check the Character Palette and Show input menu in menu bar boxes: Now, you will be able to open the Character Palette from the screen-top menu. Character Palette can also be accessed through Font Panel. Open it with the Command + T keyboard shortcut. Click on the action wheel at the bottom of the panel and choose Characters... to open the Character Palette. Check the Character Palette box to find what you need. Images here range from the familiar Command symbol on the Mac keyboard to zodiac symbols, to chess pieces and cards icons, to mathematical and musical signs, various daily life shapes, including icons of telephones, pens and pencils, scissors, airplanes, and so on. And there are Greek letters that can be used in scientific papers (for instance, the letter ∏). To import the Character Palette symbols into an iWork document, just click-and-drag them into your project. The beauty of the Character Palette characters is that they behave like letters. You can change the color and font size in the Format bar and add shadows and other effects in the Graphics Inspector or via the Font Panel. To use the Character Palette characters as clip art, we need to turn them into images in PDF, JPEG, or some other format. How to do it... Let's see how a character can be turned into a piece of clip art. This applies to both letters and symbols from the Character Palette. Open Character Palette | Symbols | Miscellaneous Symbols. In this folder, we have a selection of scissors that can be used to show, with a dotted line, where to cut out coupons or forms from brochures, flyers, posters, and other marketing material. Click on the scissors symbol with a snapped off blade and drag it into an iWork document. Select the symbol in the same way as you would select a letter, and enlarge it substantially. To enlarge, click on the Font Size drop-down menu in the Format bar and select a bigger size, or use the shortcut key Command + plus sign (hit the plus key several times). Next, turn the scissors into an image. Make a screenshot (Command + Shift + 4) or use the Print dialog to make a PDF or a JPEG. You can crop the image in iPhoto or Preview before using it in iWork, or you can import it straight into your iWork project and remove the white background with the Alpha tool. If Alpha is not in your toolbar, you can find it under Format |Instant Alpha. Move the scissors onto the dotted line of your coupon. Now, the blade that is snapped in half appears to be cutting through the dotted line. Remember that you can rotate the clip art image to put scissors either on the horizontal or on the vertical sides of the coupon. Use other scissors symbols from the Character Palette, if they are more suitable for your project. Store the "scissors" clip art in iPhoto or another folder for future use if you are likely to need it again. There's more... There are other easily accessible sources of clip art. MS Office clip art is compatible If you have kept your old copy of MS Office, nothing is simpler than copy-pasting or draggingand- dropping clip art from the Office folder right into your iWork project. When using clip art, it's worth remembering that some predrawn images quickly become dated. For example, if you put a clip art image of an incandescent lamp in your marketing documents for electric works, it may give an impression that you are not familiar with more modern and economic lighting technologies. Likewise, a clip art image of an old-fashioned computer with a CRT display put on your promotional literature for computer services can send the wrong message, because modern machines use flat-screen displays. Wikipedia/Wikimedia Look on Wikipedia for free generic images. Search for articles about tools, domestic appliances, furniture, houses, and various other objects. Most articles have downloadable images with no copyright restrictions for re-use. They can easily be made into clip art. This image of a hammer from Wikipedia can be used for any articles about DIY (do-it-yourself) projects. Create your own clip art Above all, it is fun to create your own clip art in iWork. For example, take a few snapshots with your digital camera or cell phone, put them in one of iWork's shapes, and get an original piece of clip art. It could be a nice way to involve children in your project.
Read more
  • 0
  • 0
  • 2759

article-image-organizing-your-balsamiq-files
Packt
09 Oct 2012
3 min read
Save for later

Organizing your Balsamiq files

Packt
09 Oct 2012
3 min read
There are two important things to note about organizing your files in Balsamiq: Keep all of your .bmml files together. The assets folder houses everything else, that is, artwork, logos, PDFs, PSDs, symbols, and so on, as shown in the following screenshot: Naming your files Naming your files in Balsamiq is very important. This is because Balsamiq does not automatically remember the order in which you organized your files after you closed them. Balsamiq will reopen them in the order in which they are sitting in a folder. There are, however, two ways you can gain greater control. Alphabetically You could alphabetize your files, although this could pose a problem as you add and delete files, requiring you to carefully name the new files so that they open in the same order as before. While it is a fine solution, the time it takes to ensure proper alphabetization does not seem worth the effort. Numbering The second, and more productive way, to name your files is to not name them at all, but instead to number them. For example, after naming a new .bmml file, add a number to the end of it in sequential order, for example, filename_1, filename_2, filename_3, and so on. Subpages, in turn, become filename_1a, filename_1b, filename_1c, and so on. Keep in mind, however, that if you add, delete, or modify numbered files, you may still have to modify the remaining page numbers accordingly. Nevertheless, I suspect you will find it to be easier than alphabetizing. Another way to number your files can be found on Balsamiq's website. The link to the exact page is a bit long. Go to http://www.balsamiq.com/ and do a search for Managing Projects in Mockups for Desktop. In the article, they recommend an alternate method of numbering your files by 10s, for example, filename_10, filename_20, filename_30, and so on. The idea being that as you add or remove pages, you can do so incrementally, rather than having to do a complete renumbering each time. In other words, you could add numbers between 11 and 19 and still be fine. Keep in mind that if you choose to use single digits, be sure to add a zero before the filename for consistency and to ensure proper file folder organization, for example, filename_05, filename_06, filename_07, and so on. How you name or number your files is completely up to you. These tips are simply recommendations to consider. The bottom line is to find a system for naming your files that works for you and to stick with it. You will be glad you did.
Read more
  • 0
  • 0
  • 3258

article-image-importing-videos-and-basic-editing-mechanics
Packt
01 Oct 2012
8 min read
Save for later

Importing videos and basic editing mechanics

Packt
01 Oct 2012
8 min read
Importing from a tapeless video camera Chances are, if you've bought a video camera in the last few years, it doesn't record to tape; it records to some form of tapeless media. In most consumer and prosumer cameras, this is typically an SD card, but could also be an internal drive, other various solid-state memory cards, or the thankfully short-lived trend of recordable mini DVDs. In the professional world, examples include Compact Flash, P2 cards (usually found in Panasonic models), SxS cards (many Sony and JVC models, Arri Alexa), or some other form of internal flash storage. How to do it... Plug your camera in to your Mac's USB port, or if you're using a higher-end setup with a capture box, plug the box into likely your FireWire or Thunderbolt box. If your camera uses an SD card as its storage medium, you can also simply stick the SD card into your Mac's card reader or external reader. If you are plugging the camera directly in, turn it on, and set it to the device's playback mode. If FCPX is running, it should automatically launch the Import from Camera window. If it does not, click on the Import from Camera icon in the left of the toolbar. You will see thumbnails of all of your camera's clips. You can easily scrub through them simply by passing your mouse over each one. You can import clips one at a time by selecting a range and then clicking on Import Selected… or you can simply highlight them all and click on Import All… . To select a range, simply move your mouse over a clip until you find the point where you want to start and hit I on your keyboard. Then scrub ahead until you reach where you want the clip to end and hit O. Whether you chose to select one, a few, or all your clips, once you click on the Import button you will arrive at the Import options screen. Choose what event you want your clips to live in, choose if you want to transcode the clips, and select any analyses you want FCPX to perform on the clips as it imports them. Click on Import. FCPX begins the import process. You can close the window and begin editing immediately! How it works... The reason you can edit so quickly, even if you're importing a massive amount of footage, is thanks to some clever programming on Apple's part. While it might take a few minutes or even longer to import all the media off of your camera or memory card, FCPX will access the media directly on the original storage device, until it has finished its import process, and then switch over to the newly imported versions. There's more... Creating a camera archive Creating a camera archive is the simplest and best way to make a backup of your raw footage. Tapeless cameras often store their media in really weird-looking ways with complex folder structures. In many cases, FCPX needs that exact folder structure in order to easily import the media. A camera archive essentially takes a snapshot or image of your camera's currently stored media and saves it to one simple file that you can access in FCPX over and over again. This of course also frees you to delete the contents of the memory card or media drive and reuse it for another shoot. In the Camera Import window, make sure your camera is selected in the left column and click on the Create Archive button in the bottom left corner. The resulting window will let you name the archive and pick a destination drive. Obviously, store your archive on an external drive if it's for backup purposes. If you were to keep it on the same drive as your FCPX system and the drive fails, you'd lose your backup as well! The process creates a proprietary disk image with the original file structure of the memory card. FCPX needs the original file structure (not just the video files) in order to properly capture from the card. By default, it stores the archive in a folder called Final Cut Camera Archives on whatever drive you selected. Later when you need to reimport from a camera archive, simply open the Camera Import window again, and if you don't see your needed archive under Camera Archives on the left, click on Open Archive… and find it in the resulting window. To import all or not to import all If you've got the time, there's nothing to stop you from looking at each and every clip one at a time in the Import from Camera window, selecting a range, and then importing that one clip. However, that's going to take you a while as you'll have to deal with the settings window every time you click on the Import button. If you've got the storage space (and most of us do today), just import everything and worry about weeding out the trash later. But what about XYZ format? There are two web pages you should bookmark to keep up to date. One is www.apple.com/finalcutpro/specs/. This web page lists most of the formats FCPX can work with. Expect this list to grow with future versions. The second site is help.apple.com/finalcutpro/cameras/en/index.html. This web site lets you search camera models for compatibility with FCPX. Just because a format isn't listed on Apple's specs page, doesn't mean it's impossible to work with. Many camera manufacturers release plugins which enhance a program's capabilities. One great example is Canon (www.canon.com), who released a plugin for FCPX allowing users to import MXF files from a wide variety of their cameras. Importing MTS, M2TS, and M2T files If you've ever browsed the file structure of a memory card pulled from an AVCHD camera, you'll have seen a somewhat complex system of files and folders and almost nothing resembling a normal video file. Deep inside you're likely to find files with the extension .mts, .m2ts, or .m2t (on some HDV cameras). By themselves, these files are sitting ducks, unable to be read by most basic video playback software or imported directly by FCPX. But somehow, once you open up the Import from Camera window in FCPX, FCPX is able to translate all that apparent gobbledygook from the memory card into movie files. FCPX needs that gobbledygook to import the footage. But what if someone has given you a hard drive full of nothing but these standalone files? You'll need to convert or rewrap (explained in the following section) the clips before heading in to FCPX. Getting ready There are a number of programs out there that can tackle this task, but a highly recommended one is ClipWrap (http://www.divergentmedia.com/clipwrap). There is a trial, but you'll probably want to go ahead and buy the full version. How to do it... Open ClipWrap. Drag-and-drop your video files (ending in .mts, .m2ts, or .m2t) into the main interface. Set a destination for your new files under Movie Destination. Click on the drop-down menu titled Output Format. You can choose to convert the files to a number of formats including ProRes 422 (the same format that is created when you select the Create optimized media option in FCPX). A faster, space-saving option, however, is to leave the default setting, Rewrap (don't alter video samples): Click on Convert. When the process is done, you will have new video files that end in .mov and can be directly imported into FCPX via File | Import | Files. How it works... In the previous exercise, we chose not to transcode/convert the video files into another format. What we did was take the video and audio stream out of one container (.mts, .m2ts, or .m2t) and put it into another (QuickTime, seen as .mov). It may sound crazy at first, but we basically took the birthday present (the video and audio) out of an ugly gift box that FCPX won't even open and put it into a prettier one that FCPX likes. There's more... Other alternatives ClipWrap is far from the only solution out there, but it is definitely one of the best. The appendix of this book covers the basics of Compressor, Apple's compression software which can't convert raw AVCHD files in most cases, but can convert just about any file that QuickTime can play. The software company, iSkySoft, (www.iskysoft.com) makes a large number of video conversion tools for a reasonable price. If you're looking for a fully featured video encoding software package, look no further than Telestream Episode (www.telestream. net) or Sorenson Squeeze (www.sorensonmedia.com). These two applications are expensive, but can take just about any video file format out there and transcode it to almost anything else, with a wide variety of customizable settings. Rewrapping or transcoding As mentioned in step 3 in the previous section, we could have chosen to transcode to ProRes 422 instead of rewrapping. This is a totally fine option, just know the differences: transcoding, takes much longer, it takes up much more file space, but on the plus side, it is Final Cut Pro X's favorite format (because it's native to FCPX, made by Apple for Apple) and you may save time in the actual editing process by working with a faster more efficient codec once inside FCPX. If you chose to rewrap, you still have the option to transcode when you import into FCPX.
Read more
  • 0
  • 0
  • 1637

article-image-planning-your-site-adobe-muse
Packt
27 Sep 2012
11 min read
Save for later

Planning Your Site in Adobe Muse

Packt
27 Sep 2012
11 min read
Page layouts The layout of your website can be a deciding factor on whether your visitors will stay on your website or leave with an impatient click. You could think of the layout as a map. If it's easy for the visitors to "read" the map, they are more likely to stick around and find the content you're providing. Let's take a look at some of the typical layouts we see on the Web today. Bread and butter layouts When we're designing a layout for a web page, there are a number of sections that we need to include. These sections can be broken into the following: Consistent content: This does not change throughout the site. Examples of this type of content are logos, navigation bars, and footers. Changing content: This is the part of the page that changes throughout the site, usually the main content. In some situations, the content of the sidebar may also change. A web designer's job is to create a layout that keeps the visitor focused on the content while keeping it nice and easy to navigate around the site. Some examples of conventional or bread and butter site layouts are shown in the following figure: You have a very short amount of time to capture a visitor's attention. So by choosing one of these basic layouts, you're using a tried and tested setup, which many web users will feel at home with. Don't worry that these layouts look "boxy". You can use images, colors, and typefaces, which complement the purpose of your site to completely disguise the fact that every web page is essentially made up of boxes. The bread and butter layouts featured previously are well-tested guides; however, there is absolutely no obligation for you to use one of these. What appears on a typical web page? So we've seen some basic layouts. Now we'll look at some of the elements that appear on (nearly) every web page. Logo The logo is the part of a company's overall branding and identity, and appears at the top of each page on the site along with the company name and tagline, just as it would on printed forms of marketing, such as business cards, brochures, and letterheads. This identity block increases brand recognition and ensures users know that the pages they're viewing are part of a single site. Frequently, the logo is also a link back to the home page of the site. Navigation bar The navigation for your site should be easy to use and easy to find. Just like the logo, it should appear near the top of the page. You may decide to use a horizontal menu across the top of the page, a vertical menu in a sidebar, or a combination of the two. Either way, your main navigation should be visible "above the fold", that is, any area of a web page that can be viewed without visitors having to scroll. Content Content is the King. This is what your visitors have come for. If the visitors can't find what they're looking for, they will move on very quickly. The main content is an important focal point in your design; don't waste time fling it with unnecessary "stuff". Footer Sitting at the bottom of the page, the footer usually holds copyright information, contact links information, and legalities of the site. Some designers have become very imaginative with footers and use this area to hold additional links, tweets, and "about me" information. The footer clearly separates the main content from the end of the page and indicates to users that they're at the bottom of the page. In the following screenshot, you can see a page from the Apple website, which is highly regarded for its aesthetic design. Each section is clearly delineated. If you keep in mind the idea of your site's layout as a map, then you can determine where you want to lead your visitors on the site. Wireframes Wireframing is an important part of the design process for both simple and complex projects. If you're creating a website for a client, a wireframe is a great tool for communicating your ideas visually at an early stage rather than just having a verbal description. If you're creating a website for yourself, the wireframe helps to clarify what is required on each page of your website. It can be considered an overlap between the planning process and the design process. Creating a simple wireframe ensures that your page designs take into account all of the elements you'll add to your pages and where they will be positioned. Wireframes are cost-effective because the time spent in the initial stages potentially saves you from losing much more time revising the design at a later stage. Wireframes can be created in several ways, including pen and paper and computer-based tools. When it comes to computer-based applications for wireframing, there are many options available. Some designers use Photoshop, Illustrator, or even InDesign to put together their wireframes. Specific wireframing software packages that are popular with web designers include Balsamiq and OmniGraffe. Wireframes and Mockups and Prototypes. Oh my! You may hear web designers refer to wireframes, mockups, and prototypes. Although these terms are sometimes used interchangeably, it's important to understand that they are three different things. A wireframe is a basic illustration showing the structure and components of a web page. A mockup is an image file focusing on the design elements in the site. It contains the graphics and other page elements that make up the web page but may contain dummy text and images. A prototype is an almost-complete or semi-functional web page, constructed with HTML and CSS. Prototypes give the client (or yourself) the ability to click around and check out how the final site will work. What to include in a wireframe? Think about which design elements will appear on each page of your website. As mentioned already, most websites will have elements such as logos, navigation, search bars, and footers in consistent positions throughout the site. Next, think about any extra elements that may be specific to individual pages. These include graphics and dynamic widgets. Once you know what's required, you can start to create your wireframe based on these elements. Some designers like to create their wireframes with the "big picture" in mind. Once the basic layout is in place, they get feedback from the client and revise the wireframe if necessary. Others like to create a very detailed wireframe for each page on the site, including every single design element on the list before showing it to the client. Wireframes let us try out several different ideas before settling on our favorite design, which can then be brought forward to the mockup stage. Obviously our focus in this book is on using Muse, but I would urge you not to rule out using paper sketches. It's a great way to quickly get ideas out of your head and into a tangible, visible layout. Web.without.words (www.webwithoutwords.com) is an interesting website dedicated to showing popular and well-known sites as wireframes. The text and images on each site are blocked out and it's a nice way to look at web pages and see how they can be broken down into simple boxes without getting caught up in the content. Wireframes with Muse So what are the advantages of using Muse to create our wireframes? Well, Muse not only lets you create wireframes, but it also allows you to quickly create prototypes using those wireframes. This means you can show clients the functionality of the website with the basic layout. The prototype produced by Muse can be reviewed on any web browser giving the client a good idea of how the site will appear. This kind of early testing can help alleviate time-consuming problems further down the line of the design process. We're going to prepare a site and wireframe now for a fictitious website about windsurfing. First, we'll create a new site, and then add pages in the Plan view. Site structure with Plan view. Let's start by creating a new site. Open Muse. Choose File | New Site. In the New Site dialog box, set Page Width to 960 and Min Height to 800 pixels. Set Margins to 0 all around and Padding Top and Bottom to 10 pixels each. Set the number of Columns to 16. The columns appear as guidelines on the page and we use them to help us align the design elements on our layout. Note that Gutter is set to 20 by default, leave this as it is. The Column Width is calculated by Muse and you should see a value of 41 appear automatically in that field. Remember that all of these values can be changed later if necessary. Click on OK. The Plan view opens and you'll see a thumbnail representing the Home page at the top left, and a thumbnail representing the A-Master page on the bottom pane. Save your site right away by selecting File | Save Site. Give it a descriptive name you'll recognize, such as Windsurf.muse. To create new pages, click on the plus (+) sign to the right of or below the existing pages, and then click on the page's name field to type its name. Click on the plus sign to the right of the Home page and name the new page Gear. Click on the plus sign below the Gear page to add a subpage and name that page Sails. Click on the plus sign to the right of the Sails page and name the new page Boards. Sails and Boards are now on the same level and are subpages of the Gear page. Click on the plus sign to the right of the Gear page and name the new page Learning. Click on the plus sign to the right of Learning and add one more page called Contact. Your Plan view should now look like the following screenshot: Working with thumbnails in the Plan view It's easy to add, delete, reposition, or duplicate pages when working in the Plan view. Right-click (Win) or Ctrl + click (Mac) on a thumbnail to see a contextual menu. This menu provides every option for managing your pages. In the previous screenshot, you can see the menu that appears when you right-click/Ctrl + click.   New Child Page: This option creates a new blank page at a lower level as the current thumbnail. New Sibling Page: This option creates a new blank page at the same level as the current thumbnail. Duplicate Page: This option makes an exact copy of the current page. This is most useful when you have added content and applied some formatting. Delete Page: This option gets rid of the page. Rename Page: This option allows us to change the name of the page. Go to Page: This option opens up the current page in the Design view. Page Properties: This option opens the Page Properties dialog box allowing you to set properties for the current page only. Reset Page Properties: This option reverts to the original settings for the page. Export Page: This option allows you to export your page as HTML and CSS. Menu Options: This option allows you to choose how the page will be included (or not included) in the automatically-created menu. Masters: This option lets you choose which Master design will be applied to the page. The context menu is not the only way to get to these options, for example the most common tasks in the Plan view can be completed as follows: You can rename a page by double-clicking on the page name You can delete a page by hovering your mouse over the thumbnail and then clicking on the x icon that appears in the top-right corner To reposition a page in your site map hierarchy, you can drag-and-drop a thumbnail on the same level or on a sublevel. Spend a couple of minutes adding, deleting, and repositioning pages so that you get a feel of creating the site structure. You'll find the Plan view to be intuitive to use and extremely fast for creating site maps. You can choose Edit | Undo to undo any of the steps you've taken. Muse tracks all the page names, and later in the design process it allows us to create menus quickly using menu widgets. All links created in the Plan view are maintained and are updated automatically if we make a change to the site structure. You can come back to the Plan view at any point during your web design process.
Read more
  • 0
  • 0
  • 4697
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
article-image-wpf-45-application-and-windows
Packt
24 Sep 2012
14 min read
Save for later

WPF 4.5 Application and Windows

Packt
24 Sep 2012
14 min read
Creating a window Windows are the typical top level controls in WPF. By default, a MainWindow class is created by the application wizard and automatically shown upon running the application. In this recipe, we'll take a look at creating and showing other windows that may be required during the lifetime of an application. Getting ready Make sure Visual Studio is up and running. How to do it... We'll create a new class derived from Window and show it when a button is clicked: Create a new WPF application named CH05.NewWindows. Right-click on the project node in Solution explorer, and select Add | Window…: In the resulting dialog, type OtherWindow in the Name textbox and click on Add. A file named OtherWindow.xaml should open in the editor. Add a TextBlock to the existing Grid, as follows: <TextBlock Text="This is the other window" FontSize="20" VerticalAlignment="Center" HorizontalAlignment="Center" /> Open MainWindow.xaml. Add a Button to the Grid with a Click event handler: <Button Content="Open Other Window" FontSize="30" Click="OnOpenOtherWindow" /> In the Click event handler, add the following code: void OnOpenOtherWindow(object sender, RoutedEventArgs e) { var other = new OtherWindow(); other.Show(); } Run the application, and click the button. The other window should appear and live happily alongside the main window: How it works... A Window is technically a ContentControl, so can contain anything. It's made visible using the Show method. This keeps the window open as long as it's not explicitly closed using the classic close button, or by calling the Close method. The Show method opens the window as modeless—meaning the user can return to the previous window without restriction. We can click the button more than once, and consequently more Window instances would show up. There's more... The first window shown can be configured using the Application.StartupUri property, typically set in App.xaml. It can be changed to any other window. For example, to show the OtherWindow from the previous section as the first window, open App.xaml and change the StartupUri property to OtherWindow.xaml: StartupUri="OtherWindow.xaml" Selecting the startup window dynamically Sometimes the first window is not known in advance, perhaps depending on some state or setting. In this case, the StartupUri property is not helpful. We can safely delete it, and provide the initial window (or even windows) by overriding the Application.OnStartup method as follows (you'll need to add a reference to the System.Configuration assembly for the following to compile): protected override void OnStartup(StartupEventArgs e) {    Window mainWindow = null;    // check some state or setting as appropriate          if(ConfigurationManager.AppSettings["AdvancedMode"] == "1")       mainWindow = new OtherWindow();    else       mainWindow = new MainWindow();    mainWindow.Show(); } This allows complete flexibility in determining what window or windows should appear at application startup. Accessing command line arguments The WPF application created by the New Project wizard does not expose the ubiquitous Main method. WPF provides this for us – it instantiates the Application object and eventually loads the main window pointed to by the StartupUri property. The Main method, however, is not just a starting point for managed code, but also provides an array of strings as the command line arguments passed to the executable (if any). As Main is now beyond our control, how do we get the command line arguments? Fortunately, the same OnStartup method provides a StartupEventArgs object, in which the Args property is mirrored from Main. The downloadable source for this chapter contains the project CH05.CommandLineArgs, which shows an example of its usage. Here's the OnStartup override: protected override void OnStartup(StartupEventArgs e) { string text = "Hello, default!"; if(e.Args.Length > 0) text = e.Args[0]; var win = new MainWindow(text); win.Show(); } The MainWindow instance constructor has been modified to accept a string that is later used by the window. If a command line argument is supplied, it is used. Creating a dialog box A dialog box is a Window that is typically used to get some data from the user, before some operation can proceed. This is sometimes referred to as a modal window (as opposed to modeless, or non-modal). In this recipe, we'll take a look at how to create and manage such a dialog box. Getting ready Make sure Visual Studio is up and running. How to do it... We'll create a dialog box that's invoked from the main window to request some information from the user: Create a new WPF application named CH05.Dialogs. Add a new Window named DetailsDialog.xaml (a DetailsDialog class is created). Visual Studio opens DetailsDialog.xaml. Set some Window properties: FontSize to 16, ResizeMode to NoResize, SizeToContent to Height, and make sure the Width is set to 300: ResizeMode="NoResize" SizeToContent="Height" Width="300" FontSize="16" Add four rows and two columns to the existing Grid, and add some controls for a simple data entry dialog as follows: <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <TextBlock Text="Please enter details:" Grid.ColumnSpan="2" Margin="4,4,4,20" HorizontalAlignment="Center"/> <TextBlock Text="Name:" Grid.Row="1" Margin="4"/> <TextBox Grid.Column="1" Grid.Row="1" Margin="4" x_Name="_name"/> <TextBlock Text="City:" Grid.Row="2" Margin="4"/> <TextBox Grid.Column="1" Grid.Row="2" Margin="4" x_Name="_city"/> <StackPanel Grid.Row="3" Orientation="Horizontal" Margin="4,20,4,4" Grid.ColumnSpan="2" HorizontalAlignment="Center"> <Button Content="OK" Margin="4"  /> <Button Content="Cancel" Margin="4" /> </StackPanel> This is how it should look in the designer: The dialog should expose two properties for the name and city the user has typed in. Open DetailsDialog.xaml.cs. Add two simple properties: public string FullName { get; private set; } public string City { get; private set; } We need to show the dialog from somewhere in the main window. Open MainWindow.xaml, and add the following markup to the existing Grid: <Grid.RowDefinitions>     <RowDefinition Height="Auto" />     <RowDefinition /> </Grid.RowDefinitions> <Button Content="Enter Data" Click="OnEnterData"         Margin="4" FontSize="16"/> <TextBlock FontSize="24" x_Name="_text" Grid.Row="1"     VerticalAlignment="Center" HorizontalAlignment="Center"/> In the OnEnterData handler, add the following: private void OnEnterData(object sender, RoutedEventArgs e) { var dlg = new DetailsDialog(); if(dlg.ShowDialog() == true) { _text.Text = string.Format( "Hi, {0}! I see you live in {1}.", dlg.FullName, dlg.City); } } Run the application. Click the button and watch the dialog appear. The buttons don't work yet, so your only choice is to close the dialog using the regular close button. Clearly, the return value from ShowDialog is not true in this case. When the OK button is clicked, the properties should be set accordingly. Add a Click event handler to the OK button, with the following code: private void OnOK(object sender, RoutedEventArgs e) { FullName = _name.Text; City = _city.Text; DialogResult = true; Close(); } The Close method dismisses the dialog, returning control to the caller. The DialogResult property indicates the returned value from the call to ShowDialog when the dialog is closed. Add a Click event handler for the Cancel button with the following code: private void OnCancel(object sender, RoutedEventArgs e) { DialogResult = false; Close(); } Run the application and click the button. Enter some data and click on OK: You will see the following window: How it works... A dialog box in WPF is nothing more than a regular window shown using ShowDialog instead of Show. This forces the user to dismiss the window before she can return to the invoking window. ShowDialog returns a Nullable (can be written as bool? in C#), meaning it can have three values: true, false, and null. The meaning of the return value is mostly up to the application, but typically true indicates the user dismissed the dialog with the intention of making something happen (usually, by clicking some OK or other confirmation button), and false means the user changed her mind, and would like to abort. The null value can be used as a third indicator to some other application-defined condition. The DialogResult property indicates the value returned from ShowDialog because there is no other way to convey the return value from the dialog invocation directly. That's why the OK button handler sets it to true and the Cancel button handler sets it to false (this also happens when the regular close button is clicked, or Alt + F4 is pressed). Most dialog boxes are not resizable. This is indicated with the ResizeMode property of the Window set to NoResize. However, because of WPF's flexible layout, it certainly is relatively easy to keep a dialog resizable (and still manageable) where it makes sense (such as when entering a potentially large amount of text in a TextBox – it would make sense if the TextBox could grow if the dialog is enlarged). There's more... Most dialogs can be dismissed by pressing Enter (indicating the data should be used) or pressing Esc (indicating no action should take place). This is possible to do by setting the OK button's IsDefault property to true and the Cancel button's IsCancel property to true. The default button is typically drawn with a heavier border to indicate it's the default button, although this eventually depends on the button's control template. If these settings are specified, the handler for the Cancel button is not needed. Clicking Cancel or pressing Esc automatically closes the dialog (and sets DiaglogResult to false). The OK button handler is still needed as usual, but it may be invoked by pressing Enter, no matter what control has the keyboard focus within the Window. The CH05.DefaultButtons project from the downloadable source for this chapter demonstrates this in action. Modeless dialogs A dialog can be show as modeless, meaning it does not force the user to dismiss it before returning to other windows in the application. This is done with the usual Show method call – just like any Window. The term dialog in this case usually denotes some information expected from the user that affects other windows, sometimes with the help of another button labelled "Apply". The problem here is mostly logical—how to convey the information change. The best way would be using data binding, rather than manually modifying various objects. We'll take an extensive look at data binding in the next chapter. Using the common dialog boxes Windows has its own built-in dialog boxes for common operations, such as opening files, saving a file, and printing. Using these dialogs is very intuitive from the user's perspective, because she has probably used those dialogs before in other applications. WPF wraps some of these (native) dialogs. In this recipe, we'll see how to use some of the common dialogs. Getting ready Make sure Visual Studio is up and running. How to do it... We'll create a simple image viewer that uses the Open common dialog box to allow the user to select an image file to view: Create a new WPF Application named CH05.CommonDialogs. Open MainWindow.xaml. Add the following markup to the existing Grid: <Grid.RowDefinitions>     <RowDefinition Height="Auto" />     <RowDefinition /> </Grid.RowDefinitions> <Button Content="Open Image" FontSize="20" Click="OnOpenImage"         HorizontalAlignment="Center" Margin="4" /> <Image Grid.Row="1" x_Name="_img" Stretch="Uniform" /> Add a Click event handler for the button. In the handler, we'll first create an OpenFileDialog instance and initialize it (add a using to the Microsoft.Win32 namespace): void OnOpenImage(object sender, RoutedEventArgs e) { var dlg = new OpenFileDialog { Filter = "Image files|*.png;*.jpg;*.gif;*.bmp", Title = "Select image to open", InitialDirectory = Environment.GetFolderPath( Environment.SpecialFolder.MyPictures) }; Now we need to show the dialog and use the selected file (if any): if(dlg.ShowDialog() == true) { try { var bmp = new BitmapImage(new Uri(dlg.FileName)); _img.Source = bmp; } catch(Exception ex) { MessageBox.Show(ex.Message, "Open Image"); } } Run the application. Click the button and navigate to an image file and select it. You should see something like the following: How it works... The OpenFileDialog class wraps the Win32 open/save file dialog, providing easy enough access to its capabilities. It's just a matter of instantiating the object, setting some properties, such as the file types (Filter property) and then calling ShowDialog. This call, in turn, returns true if the user selected a file and false otherwise (null is never returned, although the return type is still defined as Nullable for consistency). The look of the Open file dialog box may be different in various Windows versions. This is mostly unimportant unless some automated UI testing is done. In this case, the way the dialog looks or operates may have to be taken into consideration when creating the tests. The filename itself is returned in the FileName property (full path). Multiple selections are possible by setting the MultiSelect property to true (in this case the FileNames property returns the selected files). There's more... WPF similarly wraps the Save As common dialog with the SaveFileDialog class (in the Microsoft.Win32 namespace as well). Its use is very similar to OpenFileDialog (in fact, both inherit from the abstract FileDialog class). What about folder selection (instead of files)? The WPF OpenFileDialog does not support that. One solution is to use Windows Forms' FolderBrowseDialog class. Another good solution is to use the Windows API Code Pack described shortly. Another common dialog box WPF wraps is PrintDialog (in System.Windows.Controls). This shows the familiar print dialog, with options to select a printer, orientation, and so on. The most straightforward way to print would be calling PrintVisual (after calling ShowDialog), providing anything that derives from the Visual abstract class (which include all elements). General printing is a complex topic and is beyond the scope of this book. What about colors and fonts? Windows also provides common dialogs for selecting colors and fonts. However, these are not wrapped by WPF. There are several alternatives: Use the equivalent Windows Forms classes (FontDialog and ColorDialog, both from System.Windows.Forms) Wrap the native dialogs yourself Look for alternatives on the Web The first option is possible, but has two drawbacks: first, it requires adding reference to the System.Windows.Forms assembly; this adds a dependency at compile time, and increases memory consumption at run time, for very little gain. The second drawback has to do with the natural mismatch between Windows Forms and WPF. For example, ColorDialog returns a color as a System.Drawing.Color, but WPF uses System.Windows.Media.Color. This requires mapping a GDI+ color (WinForms) to WPF's color, which is cumbersome at best. The second option of doing your own wrapping is a non-trivial undertaking and requires good interop knowledge. The other downside is that the default color and font common dialogs are pretty old (especially the color dialog), so there's much room for improvement. The third option is probably the best one. There are more than a few good candidates for color and font pickers. For a color dialog, for example, you can use the ColorPicker or ColorCanvas provided with the Extended WPF toolkit library on CodePlex (http://wpftoolkit.codeplex.com/). Here's how these may look (ColorCanvas on the left-hand side, and one of the possible views of ColorPicker on the right-hand side): The Windows API Code Pack The Windows API Code Pack is a Microsoft project on CodePlex (http://archive.msdn.microsoft.com/WindowsAPICodePack) that provides many .NET wrappers to native Windows features, in various areas, such as shell, networking, Windows 7 features (this is less important now as WPF 4 added first class support for Windows 7), power management, and DirectX. One of the Shell features in the library is a wrapper for the Open dialog box that allows selecting a folder instead of a file. This has no dependency on the WinForms assembly.
Read more
  • 0
  • 0
  • 5420

article-image-extgwt-rich-internet-application-crafting-ui-real-estate
Packt
14 Sep 2012
3 min read
Save for later

ExtGWT Rich Internet Application: Crafting UI Real Estate

Packt
14 Sep 2012
3 min read
(For more resources on ExtGwt, see here.) Introduction Layouts are a fundamental part of the GXT library. They provide the ability to create flexible and beautiful application UIs easily. However, with this power comes a level of complexity. A solid understanding of layouts is the key to using the library effectively. With GWT Panels, the panel itself is responsible for creating the panel's markup and inserting its children at the appropriate location, and creating appropriate markup as changes are made. Unlike GWT Panels, LayoutContainer (a concrete GXT container with support for layouts) does not physically connect its child components to the container's DOM. The Document Object Model is used to represent an HTML document in a tree-like structure in the browser's memory. We can dynamically change the content of the HTML page by manipulating the DOM. Rather, it is the job of the layout to both build the internal structure of the container, and to connect its child widgets. In order for a GXT container's HTML to be rendered, the container's layout() method must execute. This is different from GWT panels, in which the HTML is rendered when the components are attached to the panel. There are several ways in which the layout can execute. For now, let's go with the simplest case in which the layout executes when the container is attached. Attached is a GWT term that indicates that the widget is part of the browser's DOM. Attaching and detaching could be a subject on its own, so let's just assume it means when the widget is added to and removed from the page. When we add a container to RootPanel (for example, RootPanel.get(). add(container)), the container will be attached, and the container's layout will execute, generating the needed HTML markup. If we add another component to the now rendered container, (container.add(new Label("New Item"))) we will have to manually execute/ refresh the container (container.layout()) for the additions (as well as removals) to be effected. This sort of Lazy-Rendering is the default behavior of GXT as of 2.2.3 with GXT 3 planning to use the same approach as GWT itself. Many GXT layouts can be used in conjunction with LayoutData, which are configuration objects assigned to each child widget within a container, and provides the layout object with additional information to be used when executing the layout. Aside from a layout being executed when the container is attached, or when layout() is called manually on the container, there are two other ways in which a layout will be executed. After a container executes its layout, it looks and sees if any of its children are containers. When it finds a child container, it then executes its layout. So as long as there is a chain of containers, the execution of layouts will cascade to the child containers. This is a very important concept as you can lay out a top-level container, and the child containers will have a chance to adjust their layouts as well. A container's layout will also execute when its size is adjusted. This is default behavior, and can be disabled. This is another important concept as it means that if a container's size is changed, the layout has a chance to update based on the container's new size.
Read more
  • 0
  • 0
  • 2112

Packt
11 Sep 2012
7 min read
Save for later

Getting Started with RapidWeaver

Packt
11 Sep 2012
7 min read
In this article by Joe Workman, the author of RapidWeaver Beginner's Guide, we will learn the basics of RapidWeaver. Mainly, we will cover the following topics: What is RapidWeaver? Installing RapidWeaver Creating our first web page Publishing our website on the Internet So strap your seat belts on and let's have some fun! What is RapidWeaver? RapidWeaver is a web development and design application for Mac that was developed by Realmac Software. It allows you to build stunning, professional websites very easily. RapidWeaver has both the novice and professional web designer covered. If you don't know (or don't want to know) how to code, RapidWeaver supports full code-free creation of your website; from blogs to site maps, photo albums to contact forms, you can build your entire website without a single line of code! Without a doubt, RapidWeaver appeals to the aspiring novice web designer. However, it does not forget about the geeky, code loving, power users! And in case you were wondering…yeah, that includes me! RapidWeaver gives us geeks full access to peek under the hood. You can effortlessly add your own HTML or PHP file to any page. You can customize the look and feel with your own CSS file. For example, maybe you would like to add your own JavaScript for the latest and greatest animations out there; not a problem, RapidWeaver has got you covered. We even have full access to the amazing WebKit Developer Tools from directly inside the application. As RapidWeaver has all of these advanced features, it really serves as a catalyst to help an aspiring, novice web designer become a geeky, code loving, power user. RapidWeaver's theme engine is a godsend for those users who are design challenged. However, it's also for those who don't want to spend time developing a site theme as they can leverage the work that some amazing theme developers have already done. Yeah, this includes me too! RapidWeaver ships with over 45 stunning themes built-in. This means that you can have a website that was designed by some world-class web designers. Each theme can be customized to your liking with just a few clicks. If you ever get tired of how your website looks, you can change your theme as often as you like. And your website content will remain 100 percent intact. Once you have your website fully constructed, RapidWeaver makes it very simple to publish your website online. It will be able to publish to pretty much every web host around through its native support for both FTP and SFTP. You will be able to publish your website for the world to see with a single click. iWeb versus RapidWeaver versus Dreamweaver RapidWeaver is most commonly compared with both iWeb and Dreamweaver. While there are definitely direct feature comparisons, we are trying to compare apples with oranges. RapidWeaver is a great tool that falls somewhere between iWeb at one end of the scale and Dreamweaver at the other end. Apple's iWeb was their first foray into personal web development software. In true Apple fashion, the application was extremely user friendly and developed beautiful websites. However, the application was really geared towards users who wanted to create a small website to share family photos and maybe have a blog. iWeb was not very extensible at all. If you ever wanted to try to steer outside the bounds of the default templates, you had to drive directly into full custom HTML. One of the biggest downsides that I came across was that once you choose the look and feel of your site, there was no going back. If you wanted to change the theme of your website, you had to redo every single page manually! For those of you who love the drag-and-drop abilities of iWeb, look no further than the RapidWeaver Stacks plugin from YourHead Software. Apple has acknowledged iWeb's shortcomings by pretty much removing iWeb from its lineup. You cannot purchase iWeb from Apple's Mac App Store. Furthermore, if you look at Apple's iLife page on their website, all traces of iWeb have been removed—if this is not a clear sign of iWeb's future, I don't know what is. Now, let's jump to the opposite end of the spectrum with Adobe Dreamweaver. Dreamweaver has a much steeper learning curve than RapidWeaver (not to mention a much steeper price tag). Dreamweaver has a lot of capability for site management and can be used collaboratively on projects, and is designed to play well with Adobe's other design software. The Adobe Creative Suite with Dreamweaver is the package of choice for very large organizational websites being developed and managed by a team, or for complex dynamic sites. I am talking about websites such as http://www.apple.com or http://www.nytimes.com. For individual and small to mid-sized business websites, I can't think of a reason why one would prefer Dreamweaver to RapidWeaver. So as I stated at the beginning, RapidWeaver provides a perfect middle ground for novice web designers and geeky code lovers! It's more than an app So far, I have talked about the RapidWeaver application itself. However, RapidWeaver is so much more than just an application. The user community that has been built around the RapidWeaver product is like nothing I have seen with any other application. The RapidWeaver forums hosted by Realmac are by far the most active and useful forums that I have seen. Users and developers spend countless hours helping each other with tips and tricks on design, code, and product support. It's a worldwide community that is truly active 24/7. You can find the forums at http://forums.realmacsoftware.com. A part of the success of the strong RapidWeaver community is the strong third-party developers that exist. RapidWeaver provides a strong and flexible platform for developers to extend the application beyond its default feature set. There are currently three primary ways to extend your RapidWeaver application: Themes, Plugins, and Stacks. As you may guess, third-party theme developers design custom themes that go above and beyond the themes that ship out of the box with RapidWeaver. With the number of amazing theme developers out there, it would be impossible not to develop a site that fits your style and looks amazing. RapidWeaver ships with 11 page styles out of the box. Blog Contact Form File Sharing HTML Code iFrame Movie Album Offsite Page Photo Album QuickTime Sitemap Styled Text However, RapidWeaver plugins can create even more page styles for you. There are a plethora of different page plugins from calendars to file uploads, and shopping carts to image galleries. To illustrate the power of RapidWeaver's platform, YourHead Software developed the Stacks plugin for fluid page layout. The Stacks plugin created an entire new class of third-party RapidWeaver developer: the stack developer! A stack is simply a widget that can be used as a building block to construct your web page. There are stacks for just about anything: animated banners, menu systems, photo galleries, or even full-blown blog integrations. If you can dream it up, there is probably a stack for it! If you have visited my website, then you should know that my origins in the RapidWeaver community are as a Stacks Developer. I think that Stacks is amazing and should probably be the first plugin that you should consider acquiring. Realmac Software has added a section on their website in order to make it easier for users to explore and locate useful third-party add-ons. So make sure that you go check it out and peruse through all the great themes, plugins, and stacks! You can browse the add-ons at http://www.realmacsoftware.com/addons.
Read more
  • 0
  • 0
  • 5867

article-image-getting-started-with-rapidweaver
Packt
09 Sep 2012
7 min read
Save for later

Getting Started withRapidWeaver

Packt
09 Sep 2012
7 min read
In this article by Joe Workman, the author of RapidWeaver Beginner's Guide, we will learn the basics of RapidWeaver. Mainly, we will cover the following topics: What is RapidWeaver? Installing RapidWeaver Creating our first web page Publishing our website on the Internet So strap your seat belts on and let's have some fun! What is RapidWeaver? RapidWeaver is a web development and design application for Mac that was developed by Realmac Software. It allows you to build stunning, professional websites very easily. RapidWeaver has both the novice and professional web designer covered. If you don't know (or don't want to know) how to code, RapidWeaver supports full code-free creation of your website; from blogs to site maps, photo albums to contact forms, you can build your entire website without a single line of code! Without a doubt, RapidWeaver appeals to the aspiring novice web designer. However, it does not forget about the geeky, code loving, power users! And in case you were wondering…yeah, that includes me! RapidWeaver gives us geeks full access to peek under the hood. You can effortlessly add your own HTML or PHP file to any page. You can customize the look and feel with your own CSS file. For example, maybe you would like to add your own JavaScript for the latest and greatest animations out there; not a problem, RapidWeaver has got you covered. We even have full access to the amazing WebKit Developer Tools from directly inside the application. As RapidWeaver has all of these advanced features, it really serves as a catalyst to help an aspiring, novice web designer become a geeky, code loving, power user. RapidWeaver's theme engine is a godsend for those users who are design challenged. However, it's also for those who don't want to spend time developing a site theme as they can leverage the work that some amazing theme developers have already done. Yeah, this includes me too! RapidWeaver ships with over 45 stunning themes built-in. This means that you can have a website that was designed by some world-class web designers. Each theme can be customized to your liking with just a few clicks. If you ever get tired of how your website looks, you can change your theme as often as you like. And your website content will remain 100 percent intact. Once you have your website fully constructed, RapidWeaver makes it very simple to publish your website online. It will be able to publish to pretty much every web host around through its native support for both FTP and SFTP. You will be able to publish your website for the world to see with a single click. iWeb versus RapidWeaver versus Dreamweaver RapidWeaver is most commonly compared with both iWeb and Dreamweaver. While there are definitely direct feature comparisons, we are trying to compare apples with oranges. RapidWeaver is a great tool that falls somewhere between iWeb at one end of the scale and Dreamweaver at the other end. Apple's iWeb was their first foray into personal web development software. In true Apple fashion, the application was extremely user friendly and developed beautiful websites. However, the application was really geared towards users who wanted to create a small website to share family photos and maybe have a blog. iWeb was not very extensible at all. If you ever wanted to try to steer outside the bounds of the default templates, you had to drive directly into full custom HTML. One of the biggest downsides that I came across was that once you choose the look and feel of your site, there was no going back. If you wanted to change the theme of your website, you had to redo every single page manually! For those of you who love the drag-and-drop abilities of iWeb, look no further than the RapidWeaver Stacks plugin from YourHead Software. Apple has acknowledged iWeb's shortcomings by pretty much removing iWeb from its lineup. You cannot purchase iWeb from Apple's Mac App Store. Furthermore, if you look at Apple's iLife page on their website, all traces of iWeb have been removed—if this is not a clear sign of iWeb's future, I don't know what is. Now, let's jump to the opposite end of the spectrum with Adobe Dreamweaver. Dreamweaver has a much steeper learning curve than RapidWeaver (not to mention a much steeper price tag). Dreamweaver has a lot of capability for site management and can be used collaboratively on projects, and is designed to play well with Adobe's other design software. The Adobe Creative Suite with Dreamweaver is the package of choice for very large organizational websites being developed and managed by a team, or for complex dynamic sites. I am talking about websites such as http://www.apple.com or http://www.nytimes.com. For individual and small to mid-sized business websites, I can't think of a reason why one would prefer Dreamweaver to RapidWeaver. So as I stated at the beginning, RapidWeaver provides a perfect middle ground for novice web designers and geeky code lovers! It's more than an app So far, I have talked about the RapidWeaver application itself. However, RapidWeaver is so much more than just an application. The user community that has been built around the RapidWeaver product is like nothing I have seen with any other application. The RapidWeaver forums hosted by Realmac are by far the most active and useful forums that I have seen. Users and developers spend countless hours helping each other with tips and tricks on design, code, and product support. It's a worldwide community that is truly active 24/7. You can find the forums at http://forums.realmacsoftware.com. A part of the success of the strong RapidWeaver community is the strong third-party developers that exist. RapidWeaver provides a strong and flexible platform for developers to extend the application beyond its default feature set. There are currently three primary ways to extend your RapidWeaver application: Themes, Plugins, and Stacks. As you may guess, third-party theme developers design custom themes that go above and beyond the themes that ship out of the box with RapidWeaver. With the number of amazing theme developers out there, it would be impossible not to develop a site that fits your style and looks amazing. RapidWeaver ships with 11 page styles out of the box. Blog Contact Form File Sharing HTML Code iFrame Movie Album Offsite Page Photo Album QuickTime Sitemap Styled Text However, RapidWeaver plugins can create even more page styles for you. There are a plethora of different page plugins from calendars to file uploads, and shopping carts to image galleries. To illustrate the power of RapidWeaver's platform, YourHead Software developed the Stacks plugin for fluid page layout. The Stacks plugin created an entire new class of third-party RapidWeaver developer: the stack developer! A stack is simply a widget that can be used as a building block to construct your web page. There are stacks for just about anything: animated banners, menu systems, photo galleries, or even full-blown blog integrations. If you can dream it up, there is probably a stack for it! If you have visited my website, then you should know that my origins in the RapidWeaver community are as a Stacks Developer. I think that Stacks is amazing and should probably be the first plugin that you should consider acquiring. Realmac Software has added a section on their website in order to make it easier for users to explore and locate useful third-party add-ons. So make sure that you go check it out and peruse through all the great themes, plugins, and stacks! You can browse the add-ons at http://www.realmacsoftware.com/addons.
Read more
  • 0
  • 0
  • 2005
article-image-loading-submitting-and-validating-forms-using-ext-js-4
Packt
31 Aug 2012
25 min read
Save for later

Working with forms using Ext JS 4

Packt
31 Aug 2012
25 min read
Ext JS 4 is Sencha’s latest JavaScript framework for developing cross-platform web applications. Built upon web standards, Ext JS provides a comprehensive library of user interface widgets and data manipulation classes to turbo-charge your application’s development. In this article, written by Stuart Ashworth and Andrew Duncan, the authors of Ext JS 4 Web Application Development Cookbook, we will cover: Constructing a complex form layout Populating your form with data Submitting your form's data Validating form fields with VTypes Creating custom VTypes Uploading files to the server Handling exceptions and callbacks This article introduces forms in Ext JS 4. We begin by creating a support ticket form in the first recipe. To get the most out of this article you should be aware that this form is used by a number of recipes throughout the article. Instead of focusing on how to configure specific fields, we demonstrate more generic tasks for working with forms. Specifically, these are populating forms, submitting forms, performing client-side validation, and handling callbacks/exceptions. Constructing a complex form layout In the previous releases of Ext JS, complicated form layouts were quite difficult to achieve. This was due to the nature of the FormLayout, which was required to display labels and error messages correctly, and how it had to be combined with other nested layouts. Ext JS 4 takes a different approach and utilizes the Ext.form.Labelable mixin, which allows form fields to be decorated with labels and error messages without requiring a specific layout to be applied to the container. This means we can combine all of the layout types the framework has to offer without having to overnest components in order to satisfy the form field's layout requirements. We will describe how to create a complex form using multiple nested layouts and demonstrate how easy it is to get a form to look exactly as we want. Our example will take the structure of a Support Ticket Request form and, once we are finished, it will look like the following screenshot: (Move the mouse over the image to enlarge.) How to do it... We start this recipe by creating a simple form panel that will contain all of the layout containers and their fields: var formPanel = Ext.create('Ext.form.Panel', { title: 'Support Ticket Request', width: 650, height: 500, renderTo: Ext.getBody(), style: 'margin: 50px', items: [] }); Now, we will create our first set of fields— the FirstName and LastName fields. These will be wrapped in an Ext.container.Container component, which is given an hbox layout so our fields appear next to each other on one line: var formPanel = Ext.create('Ext.form.Panel', { title: 'Support Ticket Request', width: 650, height: 500, renderTo: Ext.getBody(), style: 'margin: 50px', items: [{ xtype: 'container', layout: 'hbox', items: [{ xtype: 'textfield', fieldLabel: 'First Name', name: 'FirstName', labelAlign: 'top', cls: 'field-margin', flex: 1 }, { xtype: 'textfield', fieldLabel: 'Last Name', name: 'LastName', labelAlign: 'top', cls: 'field-margin', flex: 1 }] }] }); We have added a CSS class (field-margin) to each field, to provide some spacing between them. We can now add this style inside <style> tags in the head of our document: <style type="text/css"> .field-margin { margin: 10px; }</style> Next, we create a container with a column layout to position our e-mail address and telephone number fields. We nest our telephone number fields in an Ext.form.FieldContainer class , which we will discuss later in the recipe: items: [ ... { xtype: 'container', layout: 'column', items: [{ xtype: 'textfield', fieldLabel: 'Email Address', name: 'EmailAddress', labelAlign: 'top', cls: 'field-margin', columnWidth: 0.6 }, { xtype: 'fieldcontainer', layout: 'hbox', fieldLabel: 'Tel. Number', labelAlign: 'top', cls: 'field-margin', columnWidth: 0.4, items: [{ xtype: 'textfield', name: 'TelNumberCode', style: 'margin-right: 5px;', flex: 2 }, { xtype: 'textfield', name: 'TelNumber', flex: 4 }] }] } ... ] The text area and checkbox group are created and laid out in a similar way to the previous sets, by using an hbox layout: items: [ ... { xtype: 'container', layout: 'hbox', items: [{ xtype: 'textarea', fieldLabel: 'Request Details', name: 'RequestDetails', labelAlign: 'top', cls: 'field-margin', height: 250, flex: 2 }, { xtype: 'checkboxgroup', name: 'RequestType', fieldLabel: 'Request Type', labelAlign: 'top', columns: 1, cls: 'field-margin', vertical: true, items: [{ boxLabel: 'Type 1', name: 'type1', inputValue: '1' }, { boxLabel: 'Type 2', name: 'type2', inputValue: '2' }, { boxLabel: 'Type 3', name: 'type3', inputValue: '3' }, { boxLabel: 'Type 4', name: 'type4', inputValue: '4' }, { boxLabel: 'Type 5', name: 'type5', inputValue: '5' }, { boxLabel: 'Type 6', name: 'type6', inputValue: '6' }], flex: 1 }] } ... ] Finally, we add the last field, which is a file upload field, to allow users to provide attachments: items: [ ... { xtype: 'filefield', cls: 'field-margin', fieldLabel: 'Attachment', width: 300 } ... ] How it works... All Ext JS form fields inherit from the base Ext.Component class and so can be included in all of the framework's layouts. For this reason, we can include form fields as children of containers with layouts (such as hbox and column layouts) and their position and size will be calculated accordingly. Upgrade Tip: Ext JS 4 does not have a form layout meaning a level of nesting can be removed and the form fields' labels will still be displayed correctly by just specifying the fieldLabel config. The Ext.form.FieldContainer class used in step 4 is a special component that allows us to combine multiple fields into a single container, which also implements the Ext.form. Labelable mixin . This allows the container itself to display its own label that applies to all of its child fields while also giving us the opportunity to configure a layout for its child components. Populating your form with data After creating our beautifully crafted and user-friendly form we will inevitably need to populate it with some data so users can edit it. Ext JS makes this easy, and this recipe will demonstrate four simple ways of achieving it. We will start by explaining how to populate the form on a field-by-field basis, then move on to ways of populating the entire form at once. We will also cover populating it from a simple object, a Model instance, and a remote server call. Getting ready We will be using the form created in this article's first recipe as our base for this section, and many of the subsequent recipes in this article, so please look back if you are not familiar with it. All the code we will write in this recipe should be placed under the definition of this form panel. You will also require a working web server for the There's More example, which loads data from an external file. How to do it... We'll demonstrate how to populate an entire form's fields in bulk and also how to populate them individually. Populating individual fields We will start by grabbing a reference to the first name field using the items property's get method. The items property contains an instance of Ext.util. MixedCollection, which holds a reference to each of the container's child components. We use its get method to retrieve the component at the specified index: var firstNameField = formPanel.items.get(0).items.get(0); Next, we use the setValue method of the field to populate it: firstNameField.setValue('Joe'); Populating the entire form To populate the entire form, we must create a data object containing a value for each field. The property names of this object will be mapped to the corresponding form field by the field's name property. For example, the FirstName property of our requestData object will be mapped to a form field with a name property value of FirstName: var requestData = { FirstName: 'Joe', LastName: 'Bloggs', EmailAddress: 'info@swarmonline.com', TelNumberCode: '0777', TelNumber: '7777777', RequestDetails: 'This is some Request Detail body text', RequestType: { type1: true, type2: false, type3: false, type4: true, type5: true, type6: false } }; We then call the setValues method of the form panel's Ext.form.Basic instance, accessed through the getForm method, passing it our requestData variable: formPanel.getForm().setValues(requestData); How it works... Each field contains a method called setValue , which updates the field's value with the value that is passed in. We can see this in action in the first part of the How to do it section. A form panel contains an internal instance of the Ext.form.Basic class (accessible through the getForm method ), which provides all of the validation, submission, loading, and general field management that is required by a form. This class contains a setValues method , which can be used to populate all of the fields that are managed by the basic form class. This method works by simply iterating through all of the fields it contains and calling their respective setValue methods. This method accepts either a simple data object, as in our example, whose properties are mapped to fields based on the field's name property. Alternatively, an array of objects can be supplied, containing id and value properties, with the id mapping to the field's name property. The following code snippet demonstrates this usage: formPanel.getForm().setValues([{id: 'FirstName', value: 'Joe'}]);   There's more... Further to the two previously discussed methods there are two others that we will demonstrate here. Populating a form from a Model instance Being able to populate a form directly from a Model instance is extremely useful and is very simple to achieve. This allows us to easily translate our data structures into a form without having to manually map it to each field. We initially define a Model and create an instance of it (using the data object we used earlier in the recipe): Ext.define('Request', { extend: 'Ext.data.Model', fields: [ 'FirstName', 'LastName', 'EmailAddress', 'TelNumberCode', 'TelNumber', 'RequestDetails', 'RequestType' ] }); var requestModel = Ext.create('Request', requestData); Following this we call the loadRecord method of the Ext.form.Basic class and supply the Model instance as its only parameter. This will populate the form, mapping each Model field to its corresponding form field based on the name: formPanel.getForm().loadRecord(requestModel); Populating a form directly from the server It is also possible to load a form's data directly from the server through an AJAX call. Firstly, we define a JSON file, containing our request data, which will be loaded by the form: { "success": true, "data": { "FirstName": "Joe", "LastName": "Bloggs", "EmailAddress": "info@swarmonline.com", "TelNumberCode": "0777", "TelNumber": "7777777", "RequestDetails": "This is some Request Detail body text", "RequestType": { "type1": true, "type2": false, "type3": false, "type4": true, "type5": true, "type6": false } } } Notice the format of the data: we must provide a success property to indicate that the load was successful and put our form data inside a data property. Next we use the basic form's load method and provide it with a configuration object containing a url property pointing to our JSON file: formPanel.getForm().load({ url: 'requestDetails.json' }); This method automatically performs an AJAX request to the specified URL and populates the form's fields with the data that was retrieved. This is all that is required to successfully load the JSON data into the form. The basic form's load method accepts similar configuration options to a regular AJAX request Submitting your form's data Having taken care of populating the form it's now time to look at sending newly added or edited data back to the server. As with form population you'll learn just how easy this is with the Ext JS framework. There are two parts to this example. Firstly, we will submit data using the options of the basic form that wraps the form panel. The second example will demonstrate binding the form to a Model and saving our data. Getting ready We will be using the form created in the first recipe as our base for this section, so refer to the Constructing a complex form layout recipe, if you are not familiar with it. How to do it... Add a function to submit the form: var submitForm = function(){ formPanel.getForm().submit({ url: 'submit.php' }); }; Add a button to the form that calls the submitForm function: var formPanel = Ext.create('Ext.form.Panel', { ... buttons: [{ text: 'Submit Form', handler: submitForm }], items: [ ... ] }); How it works... As we learned in the previous recipe, a form panel contains an internal instance of the Ext.form.Basic class (accessible through the getForm method). The submit method in Ext.form.Basic is a shortcut to the Ext.form.action.Submit action. This class handles the form submission for us. All we are required to do is provide it with a URL and it will handle the rest. It's also possible to define the URL in the configuration for the Ext.form.Panel.. Before submitting, it must first gather the data from the form. The Ext.form.Basic class contains a getValues method, which is used to gather the data values for each form field. It does this by iterating through all fields in the form making a call to their respective getValue methods. There's more... The previous recipe demonstrated how to populate the form from a Model instance. Here we will take it a step further and use the same Model instance to submit the form as well. Submitting a form from a Model instance Extend the Model with a proxy and load the data into the form: xt.define('Request', { extend: 'Ext.data.Model', fields: ['FirstName', 'LastName', 'EmailAddress', 'TelNumberCode', 'TelNumber', 'RequestDetails', 'RequestType'], proxy: { type: 'ajax', api: { create: 'addTicketRequest.php', update: 'updateTicketRequest.php' }, reader: { type: 'json' } } }); var requestModel = Ext.create('Request', { FirstName: 'Joe', LastName: 'Bloggs', EmailAddress: 'info@swarmonline.com' }); formPanel.getForm().loadRecord(requestModel); Change the submitForm function to get the Model instance, update the record with the form data, and save the record to the server: var submitForm = function(){ var record = formPanel.getForm().getRecord(); formPanel.getForm().updateRecord(record); record.save(); }; Validating form fields with VTypes In addition to form fields' built-in validation (such as allowBlank and minLength), we can apply more advanced and more extensible validation by using VTypes. A VType (contained in the Ext.form.field.VTypes singleton) can be applied to a field and its validation logic will be executed as part of the field's periodic validation routine. A VType encapsulates a validation function, an error message (which will be displayed if the validation fails), and a regular expression mask to prevent any undesired characters from being entered into the field. This recipe will explain how to apply a VType to the e-mail address field in our example form, so that only properly formatted e-mail addresses are deemed valid and an error will be displayed if it doesn't conform to this pattern. How to do it... We will start by defining our form and its fields. We will be using our example form that was created in the first recipe of this article as our base. Now that we have a form we can add the vtype configuration option to our e-mail address field: { xtype: 'textfield', fieldLabel: 'Email Address', name: 'EmailAddress', labelAlign: 'top', cls: 'field-margin', columnWidth: 0.6, vtype: 'email' } That is all we have to do to add e-mail address validation to a field. We can see the results in the following screenshot, with an incorrectly formatted e-mail address on the left and a valid one on the right: How it works... When a field is validated it runs through various checks. When a VType is defined the associated validation routine is executed and will flag the field invalid or not . As previously mentioned, each VType has an error message coupled with it, which is displayed if it is found to be invalid, and a mask expression which prevents unwanted characters being entered. Unfortunately, only one VType can be applied to a field and so, if multiple checks are required, a custom hybrid may need to be created. See the next recipe for details on how to do this. There's more... Along with the e-mail VType, the framework provides three other VTypes that can be applied straight out of the box. These are: alpha: this restricts the field to only alphabetic characters alphnum: this VType allows only alphanumeric characters url: this ensures that the value is a valid URL Creating custom VTypes We have seen in the previous recipe how to use VTypes to apply more advanced validation to our form's fields. The built-in VTypes provided by the framework are excellent but we will often want to create custom implementations to impose more complex and domain specific validation to a field. We will walkthrough creating a custom VType to be applied to our telephone number field to ensure it is in the format that a telephone number should be. Although our telephone number field is split into two (the first field for the area code and the second for the rest of the number), for this example we will combine them so our VType is more comprehensive. For this example, we will be validating a very simple, strict telephone number format of "0777-777-7777". How to do it... We start by defining our VType's structure. This consists of a simple object literal with three properties. A function called telNumber and two strings called telNumberText (which will contain the error message text) and telNumberMask (which holds a regex to restrict the characters allowed to be entered into the field) respectively. var telNumberVType = { telNumber: function(val, field){ // function executed when field is validated // return true when field's value (val) is valid return true; }, telNumberText: 'Your Telephone Number must only include numbers and hyphens.', telNumberMask: /[d-]/ }; Next we define the regular expression that we will use to validate the field's value. We add this as a variable to the telNumber function: telNumber: function(val, field){ var telNumberRegex = /^d{4}-d{3}-d{4}$/; return true; } Once this has been done we can add the logic to this telNumber function that will decide whether the field's current value is valid. This is a simple call to the regular expression string's test method, which returns true if the value matches or false if it doesn't: telNumber: function(val, field){ var telNumberRegex = /^d{4}-d{3}-d{4}$/; return telNumberRegex.test(val); } The final step to defining our new VType is to apply it to the Ext.form.field. VTypes singleton, which is where all of the VTypes are located and where our field's validation routine will go to get its definition: Ext.apply(Ext.form.field.VTypes, telNumberVType); Now that our VType has been defined and registered with the framework, we can apply it to the field by using the vtype configuration option. The result can be seen in the following screenshot: { xtype: 'textfield', name: 'TelNumber', flex: 4, vtype: 'telNumber' } How it works... A VType consists of three parts: The validity checking function The validation error text A keystroke filtering mask (optional) VTypes rely heavily on naming conventions so they can be executed dynamically within a field's validation routine. This means that each of these three parts must follow the standard convention. The validation function's name will become the name used to reference the VType and form the prefix for the other two properties. In our example, this name was telNumber, which can be seen referencing the VType in Step 5. The error text property is then named with the VType's name prefixing the word Text (that is, telNumberText ). Similarly, the filtering mask is the VType's name followed by the word Mask (that is, telNumberMask ). The final step to create our VType is to merge it into the Ext.form.field.VTypes singleton allowing it to be accessed dynamically during validation. The Ext.apply function does this by merging the VType's three properties into the Ext.form.field.VTypes class instance. When the field is validated, and a vtype is defined, the VType's validation function is executed with the current value of the field and a reference to the field itself being passed in. If the function returns true then all is well and the routine moves on. However, if it evaluates to false the VType's Text property is retrieved and pushed onto the errors array. This message is then displayed to the user as our screenshot shown earlier. This process can be seen in the code snippet as follows, taken directly from the framework: if (vtype) { if(!vtypes[vtype](value, me)){ errors.push(me.vtypeText || vtypes[vtype +'Text']); } } There's more... It is often necessary to validate fields based on the values of other fields as well as their own. We will demonstrate this by creating a simple VType for validating that a confirm password field's value matches the value entered in an initial password field. We start by creating our VType structure as we did before: Ext.apply(Ext.form.field.VTypes, { password: function(val, field){ return false; }, passwordText: 'Your Passwords do not match.' }); We then complete the validation logic. We use the field's up method to get a reference to its parent form. Using that reference, we get the values for all of the form's fields by using the getValues method : password: function(val, field){ var parentForm = field.up('form'); // get parent form // get the form's values var formValues = parentForm.getValues(); return false; } The next step is to get the first password field's value. We do this by using an extra property ( firstPasswordFieldName) that we will specify when we add our VType to the confirm password field. This property will contain the name of the initial password field (in this example Password ). We can then compare the confirm password's value with the retrieved value and return the outcome: password: function(val, field){ var parentForm = field.up('form'); // get parent form // get the form's values var formValues = parentForm.getValues(); // get the value from the configured 'First Password' field var firstPasswordValue = formValues[field.firstPasswordFieldName]; // return true if they match return val === firstPasswordValue; } The VType is added to the confirm password field in exactly the same way as before but we must include the extra firstPasswordFieldName option to link the fields together: { xtype: 'textfield', fieldLabel: 'Confirm Password', name: 'ConfirmPassword', labelAlign: 'top', cls: 'field-margin', flex: 1, vtype: 'password', firstPasswordFieldName: 'Password' } Uploading files to the server Uploading files is very straightforward with Ext JS 4. This recipe will demonstrate how to create a basic file upload form and send the data to your server: Getting Ready This recipe requires the use of a web server for accepting the uploaded file. A PHP file is provided to handle the file upload; however, you can integrate this Ext JS code with any server-side technology you wish. How to do it... Create a simple form panel. Ext.create('Ext.form.Panel', { title: 'Document Upload', width: 400, bodyPadding: 10, renderTo: Ext.getBody(), style: 'margin: 50px', items: [], buttons: [] }); In the panel's items collection add a file field: Ext.create('Ext.form.Panel', { ... items: [{ xtype: 'filefield', name: 'document', fieldLabel: 'Document', msgTarget: 'side', allowBlank: false, anchor: '100%' }], buttons: [] }); Add a button to the panel's buttons collection to handle the form submission: Ext.create('Ext.form.Panel', { ... buttons: [{ text: 'Upload Document', handler: function(){ var form = this.up('form').getForm(); if (form.isValid()) { form.submit({ url: 'upload.php', waitMsg: 'Uploading...' }); } } }] }); How it works... Your server-side code should handle these form submissions in the same way they would handle a regular HTML file upload form. You should not have to do anything special to make your server-side code compatible with Ext JS. The example works by defining an Ext.form.field.File ( xtype: 'filefield' ), which takes care of the styling and the button for selecting local files. The form submission handler works the same way as any other form submission; however, behind the scenes the framework tweaks how the form is submitted to the server. A form with a file upload field is not submitted using an XMLHttpRequest object—instead the framework creates and submits a temporary hidden <form> element whose target is referenced to a temporary hidden <iframe>. The request header's Content-Type is set to multipart/form. When the upload is finished and the server has responded, the temporary form and <iframe> are removed. A fake XMLHttpRequest object is then created containing a responseText property (populated from the contents of the <iframe> ) to ensure that event handlers and callbacks work as if we were submitting the form using AJAX. If your server is responding to the client with JSON, you must ensure that the response Content-Type header is text/html. There's more... It's possible to customize your Ext.form.field.File. Some useful config options are highlighted as follows: buttonOnly: Boolean Setting buttonOnly: true removes the visible text field from the file field. buttonText: String If you wish to change the text in the button from the default of "Browse…" it's possible to do so by setting the buttonText config option. buttonConfig: Object Changing the entire configuration of the button is done by defining a standard Ext.button. Button config object in the buttonConfig option. Anything defined in the buttonText config option will be ignored if you use this. Handling exception and callbacks This recipe demonstrates how to handle callbacks when loading and submitting forms. This is particularly useful for two reasons: You may wish to carry our further processing once the form has been submitted (for example, display a thank you message to the user) In the unfortunate event when the submission fails, it's good to be ready and inform the user something has gone wrong and perhaps perform extra processing The recipe shows you what to do in the following circumstances: The server responds informing you the submission was successful The server responds with an unusual status code (for example, 404 , 500 , and so on) The server responds informing you the submission was unsuccessful (for example, there was a problem processing the data) The form is unable to load data because the server has sent an empty data property The form is unable to submit data because the framework has deemed the values in the form to be invalid Getting ready The following recipe requires you to submit values to a server. An example submit.php file has been provided. However, please ensure you have a web server for serving this file. How to do it... Start by creating a simple form panel: var formPanel = Ext.create('Ext.form.Panel', { title: 'Form', width: 300, bodyPadding: 10, renderTo: Ext.getBody(), style: 'margin: 50px', items: [], buttons: [] }); Add a field to the form and set allowBlank to false: var formPanel = Ext.create('Ext.form.Panel', { ... items: [{ xtype: 'textfield', fieldLabel: 'Text field', name: 'field', allowBlank: false }], buttons: [] }); Add a button to handle the forms submission and add success and failure handlers to the submit method's only parameter: var formPanel = Ext.create('Ext.form.Panel', { ... buttons: [{ text: 'Submit', handler: function(){ formPanel.getForm().submit({ url: 'submit.php', success: function(form, action){ Ext.Msg.alert('Success', action.result.message); }, failure: function(form, action){ if (action.failureType === Ext.form.action.Action. CLIENT_INVALID) { Ext.Msg.alert('CLIENT_INVALID', 'Something has been missed. Please check and try again.'); } if (action.failureType === Ext.form.action.Action. CONNECT_FAILURE) { Ext.Msg.alert('CONNECT_FAILURE', 'Status: ' + action.response.status + ': ' + action.response.statusText); } if (action.failureType === Ext.form.action.Action. SERVER_INVALID) { Ext.Msg.alert('SERVER_INVALID', action.result. message); } } }); } }] }); When you run the code, watch for the different failureTypes or the success callback: CLIENT_INVALID is fired when there is no value in the text field. The success callback is fired when the server returns true in the success property. Switch the response in submit.php file and watch for SERVER_INVALID failureType. This is fired when the success property is set to false. Finally, edit url: 'submit.php' to url: 'unknown.php' and CONNECT_FAILURE will be fired. How it works... The Ext.form.action.Submit and Ext.form.action.Load classes both have a failure and success function. One of these two functions will be called depending on the outcome of the action. The success callback is called when the action is successful and the success property is true. The failure callback , on the other hand, can be extended to look for specific reasons why the failure occurred (for example, there was an internal server error, the form did not pass client-side validation, and so on). This is done by looking at the failureType property of the action parameter. Ext.form.action.Action has four failureType static properties: CLIENT_INVALID, SERVER_INVALID, CONNECT_FAILURE, and LOAD_FAILURE, which can be used to compare with what has been returned by the server. There's more... A number of additional options are described as follows: Handling form population failures The Ext.form.action.Action.LOAD_FAILURE static property can be used in the failure callback when loading data into your form. The LOAD_FAILURE is returned as the action parameter's failureType when the success property is false or the data property contains no fields. The following code shows how this failure type can be caught inside the failure callback function: failure: function(form, action){ ... if(action.failureType == Ext.form.action.Action.LOAD_FAILURE){ Ext.Msg.alert('LOAD_FAILURE', action.result.message); } ... } An alternative to CLIENT_INVALID The isValid method in Ext.form.Basic is an alternative method for handling client-side validation before the form is submitted. isValid will return true when client-side validation passes: handler: function(){ if (formPanel.getForm().isValid()) { formPanel.getForm().submit({ url: 'submit.php' }); } }   Further resources on this subject: Ext JS 4: Working with the Grid Component [Article] Ext JS 4: Working with Tree and Form Components [Article] Infinispan Data Grid: Infinispan and JBoss AS 7 [Article]
Read more
  • 0
  • 0
  • 12644

article-image-publishing-project-various-formats-using-adobe-captivate-6
Packt
27 Aug 2012
16 min read
Save for later

Publishing the project in various formats using Adobe Captivate 6

Packt
27 Aug 2012
16 min read
Publishing to Flash In the history of Captivate, publishing to Flash has always been the primary publishing option. Even though HTML5 publishing is a game changer, publishing to Flash still is an important capability of Captivate. Remember that this publishing format is currently the only one that supports every single feature, animation, and object of Captivate. In the following exercise, we will publish our movie in Flash format using the default options: Return to the Chapter06/encoderDemo_800.cptx file. Click on the Publish icon situated right next to the Preview icon. Alternatively, you can also use the File | Publish menu. The Publish dialog box opens, as shown in the following screenshot:   The Publish dialog box is divided into four main areas: The Publish Format area (1) – This is where we choose the format in which we want to publish our movies. Basically, we can choose between three options: SWF/HTML5, Media, and Print. The other options (E-mail, FTP, and so on) are actually suboptions of the SWF/HTML5, Media, and Print formats. The Output Format Options area (2) – The content of this area depends on the format chosen in the Publish Format (1) area. The Project Information area (3) – This area is a summary of the main project preferences and metadata. Clicking on the links of this area will bring us back to the various project preferences boxes. The Advanced Options area (4) – This area provides some additional advanced publishing options. We will now move on to the actual publication of the project in Flash Format. In the Publish Format area, make sure the chosen format is SWF/HTML5. In the Flash(.swf) Options area, change the Project Title to encoderDemo_800_flash. Click on the Browse button situated just below the Folder field and choose to publish your movie in the Chapter06/Publish folder of your exercises folder. Make sure the Publish to Folder checkbox is selected. Take a quick look at the remaining options, but leave them all at their current settings. Click on the Publish button at the bottom-right corner of the Publish dialog box. When Captivate has finished publishing the movie, an information box appears on the screen asking if you want to view the output. Click on No to discard the information box and return to Captivate. We will now use the Finder (Mac) or the Windows Explorer (Windows) to take a look at the files Captivate has generated. Use the Finder (Mac) or the Windows Explorer (Window) to browse to the Chapter06/Publish folder of your exercises. Because we selected the Publish to Folder checkbox in the Publish dialog, Captivate has automatically created the encoderDemo_800_flash subfolder in the Chapter06/ Publish folder. Open the encoderDemo_800_flash subfolder to inspect its content. encoderDemo_800_flash.swf – This is the main Flash file containing the compiled version of the .cptx project encoderDemo_800_flash.html – This file is an HTML page used to embed the Flash file standard.js – is a JavaScript file used to make the Flash player work well within the HTML page demo_en.flv – is the video file used on slide 2 of the movie captivate.css – provides the necessary style rules to ensure the proper formatting of the HTML page If we want to embed the compiled Captivate movie in an existing HTML page, only the .swf file (plus, in this case, the .flv video) is needed. The HTML editor (such as Adobe Dreamweaver) will recreate the necessary HTML, JavaScript, and CSS files. Captivate and Dreamweaver Adobe Dreamweaver CS6 is the HTML editor of the Creative Suite and the industry leading solution for authoring professional web pages. Inserting a Captivate file in a Dreamweaver page is dead easy! First, move or copy the main Flash file (.swf) as well as the needed support files (in our case the .flv video file), if any, somewhere in the root folder of the Dreamweaver site. When done, use the Files panel of Dreamweaver to drag-and-drop the main swf file on the HTML page. That's it! We will now test the movie in a web browser. This is an important test as it recreates the conditions in which our students will experience our movie once in production. Double-click on the encoderDemo_800_flash.html file to open it in a web browser. Enjoy the fnal version of the demonstration that we have created together! Now that we have experienced the workfow of publishing our project to Flash with the default options, we will add some changes into the mix and create a scalable version of our project. Scalable HTML content One of the solutions about choosing the right size for our project is to use the new Scalable HTML content option of Captivate 6. Thanks to this new option, our eLearning content will be automatically resized to fit the screen on which it is viewed. Let's experiment with this option hands-on, using the following steps: If needed, return to the Chapter06/encoderDemo_800.cptx file. Click on the Publish icon situated right next to the Preview icon. Alternatively, you can also use the File | Publish menu. In the Publish Format area, make sure the chosen format is Flash(.swf) Options area. In the Flash(.swf) Options area, change the Project Title to encoderDemo_800_flashScalable. Click on the Browse button situated just below the Folder field and ensure that the publish folder still is the Chapter06/Publish folder of your exercises. Make sure the Publish to Folder checkbox is selected. In the Advanced Options section (lower-right corner of the Publish dialog), select the Scalable HTML content checkbox. Leave the remaining options at their current value and click on the Publish button at the bottom-right corner of the Publish dialog box. A message informs you that object refection is not supported in scalable content. We used object refection on slide 3 to enhance the AMELogo image. Click on Yes to discard the message and start the publishing process. When Captivate has fnished publishing the movie, an information box appears on the screen asking if you want to view the output. Click on Yes to discard the information box and open the published movie in the default web browser. During the playback, use your mouse to resize your browser window and notice how our movie is also resized in order to ft the browser window. Also notice that the refection effect we used on the AMELogo image has been discarded. Publishing to HTML5 Publishing to HTML5 is the killer new feature of Captivate 6. One of the main goals of HTML5 is to provide a plugin free paradigm. It means that the interactivity and strong visual experience brought to the Internet by the plugins should now be supported natively by the browsers and their underlying technologies (mainly HTML, CSS, and JavaScript) without the need for an extra third-party plugin. Because a plugin is no longer necessary to deliver rich interactive content, any modern browser should be capable of rendering our interactive eLearning courses. And that includes the browsers installed on mobile devices, such as Tablets and Smartphones. This is an enormous change, not only for the industry, but also for us, the Captivate users and eLearning developers. Thanks to HTML5, our students will be able to enjoy our eLearning content across all their devices. The door is open for the next revolution of our industry: the mLearning (for Mobile Learning) revolution. Blog posts To get a better idea of what's at stake with HTML5 in eLearning and mLearning, I recommend these two blog posts, available at http://blogs.adobe.com/captivate/2011/11/the-how-why-of-ipads-html5-mobile-devices-in-elearning-training-education.html by Allen Partridge on the official Adobe Captivate blog and http://rjacquez.com/the-m-in-mlearning-means-more/ by RJ Jacquez. Using the HTML5 Tracker At the time of this writing (June 2012), HTML5 is still under development. Some parts of the HTML5 specification are already final and well implemented in the browsers while other parts of the specification are still under discussion. Consequently, some features of Captivate that are supported in Flash are not yet supported in HTML5. In the following exercise, we will use the HTML5 tracker to better understand what features of our Encoder Demonstration are supported in HTML5: If needed, return to the encoderDemo_800.cptx file. Use the Window | HTML5 Tracker to open the HTML5 Tracker floating panel. The HTML5 Tracker informs us that some features that we used in this project are not (yet) supported in HTML5, as shown in the following screenshot: On slide 1 and slide 22, the Text Animations are not supported in HTML5. Same thing for the three orange arrow animations we inserted on slide 5. Close the HTML5 Tracker panel. A comprehensive list of all the objects and features that are not yet supported in the HTML5 output is available in the offcial Captivate Help at http://help.adobe.com/en_US/captivate/cp/using/WS16484b78be4e1542-74219321367c91074e-8000.html. Make sure you read that page before publishing your projects in HTML5. In the next exercise, we will publish a second version of our Encoder Demonstration using the new HTML5 publishing option. Publishing the project in HTML5 The process of publishing the project to HTML5 is very similar to the process of publishing the project to Flash. Perform the following steps to publish the project in HTML5: If needed, return to the encoderDemo_800.cptx file. Click on the Publish icon or use the File | Publish menu item to open the Publish dialog box. In the left-most column of the Publish dialog, make sure you are using the SWF/HTML5 option. Change the Project Title to encoderDemo_800_HTML5. Click on the Browse button and choose the Chapter06/publish folder of the exercises as the publish location. Make sure the Publish to Folder checkbox is selected. In the Output Format Option section, select the HTML5 checkbox. Once done, uncheck the SWF checkbox. This is the single most important setting of the entire procedure. Note that you can select both the SWF and the HTML5 options. In the Advanced Options area of the Publish dialog, deselect the Scalable HTML content checkbox. Leave the other options at their current settings and click on the Publish button. Captivate informs us that some features used in this project are not supported in HTML5. Click on Yes to discard the message and start the publication to HTML5. The process of publishing to HTML5 is much longer than the publication to Flash. One of the reasons is that Captivate needs to open the Adobe Media Encoder to convert the .flv video used in slide 2 and the Full Motion Recording of slide 13 to the .mp4 format. When the publish process is complete, a second message appears asking if you want to view the output. Click on No to discard the message and return to the standard Captivate interface. We will now use the Windows Explorer (Windows) or the Finder (Mac) to take a closer look at the generated files. Use the Windows Explorer (Windows) or the Finder (Mac) to go to the Chapter06/publish/encoderDemo_800_HTML5 folder of the exercises. You should find a bunch of files and folders in the publish/encoderDemo_800_ HTML5 folder, as follows: index.html – is the main HTML file. This is the file to load in the web browser to play the course. The /ar folder – contains all the needed sound clips in .mp3 format. The /dr folder – contains all the needed images. Notice that the mouse pointers, the slide backgrounds, as well as all the Text Captions are exported as .png images. The /vr folder – contains the needed video files in .mp4 format. The /assets folders – contains the needed CSS and JavaScript files. We will now test this version of the project in a web browser. Supported browsers and OS for HTML5 On the desktop, the HTML5 version of our eLearning project requires Internet Explorer 9 or later versions, Safari 5.1 or later versions, or Google Chrome 17 or later versions. For mobile devices, HTML5 is supported on iPads with iOS 5 or later versions. Make sure you use one of the browsers mentioned for the testing phase of this exercise. Open the .index.html. file in one of the supported browsers. When testing the HTML5 version of the project in a web browser, notice that the unsupported Text Animations of slide 1 and 22 have been replaced by a standard Text Caption with a Fade In effect. On slide 3, the effect we added on the AMELogo image is not reproduced in the HTML5 output. Surprisingly, this was not mentioned in the HTML5 tracker panel. On slide 5, the unsupported orange arrows Animations have been replaced by static images. On slide 16, the zooming animation is supported, but Text Captions that should be invisible are showing in the Zoom Destination area. Apart from the few problems mentioned in the previous list, Captivate 6 does a pretty good job in converting our demonstration to HTML5. That being said, HTML5 publishing is still an emerging technology. The room for improvement is enormous. In the coming years more parts of the HTML5 specifcation will be finalized and new techniques, tools, and framework will emerge. We will then be able to better implement HTML5 across devices, both in Captivate and throughout the entire Internet Publishing to PDF Another publishing option available in Captivate is to publish our project as an Adobe PDF document. This process is very close to the Flash publishing process we covered previously. When converting to PDF, Captivate first converts the project to Flash and then embeds the resulting .swf file in a PDF document. To read the Flash file embedded in the PDF document, the free Adobe Acrobat Reader simply contains a copy of the Flash player. Publishing the Captivate project to PDF is a great way to make the eLearning course available offline. The students can, for example, download the PDF file from a website and take the course in a train or in an airplane where no Internet connection is available. On the other hand, as the Captivate movie can be viewed offline, any Captivate feature that requires an Internet connection (such as reporting the scores to an LMS (Learning Management System)) will not work! In the following exercise, we will publish the Encoder Demonstration to PDF: Return to the Chapter06/encoderDemo_800.cptx file. Click on the Publish icon situated right next to the Preview icon. Alternatively, you can use the File | Publish menu item. In the Publish Format area, make sure the chosen format is SWF/HTML5. If needed, deselect the HTML5 checkbox and make sure the .SWF checkbox is the only one selected. In the Flash(.swf) Options area, change the Project Title to encoderDemo_800_pdf. Make sure the publish Folder still is the Chapter06/Publish folder of the exercises. Make sure the Publish to Folder checkbox is still selected. At the end of the Output Format Options area, select the Export PDF checkbox. Click on the Publish button situated in the lower-right corner of the Publish dialog. When the publishing process is complete, a message tells you that Acrobat 9 or higher is required to read the generated PDF file. Click on OK to acknowledge the message. A second information box opens. Click on No to discard the second message and close the Publish dialog. Use the Finder (Mac) or the Windows Explorer (Windows) to browse to the Chapter06/publish/encoderDemo_800_pdf folder. There should be six additional files in the Chapter06/publish/encoderDemo_800_ pdf folder. Actually, publishing to PDF is an extra option of the standard publishing to Flash feature. Delete all but the PDF file from the Chapter06/publish/encoderDemo_800_ pdf folder. Double-click on the encoderDemo_800_pdf.pdf file to open it in Adobe Acrobat. Notice that the file plays normally in Adobe Acrobat. This proves that all the necessary files and assets have been correctly embedded into the PDF file. In the next section, we will explore the third publishing option of Captivate: publishing as a standalone application. Publishing as a standalone application When publishing as a standalone application, Captivate generates an .exe file for playback on Windows or an .app file for playback on Macintosh. The .exe (Windows) or .app (Mac) file contains the compiled .swf file plus the Flash player. The advantages and disadvantages of a standalone application are similar to those of a PDF file. That is, the file can be viewed offline in a train, in an airplane, or elsewhere, but the features requiring an Internet connection will not work. In the following exercise, we will publish the Captivate file as a standalone application using the following steps: If needed, return to the Chapter06/encoderDemo_800.cptx file. Click on the Publish icon situated right next to the Preview icon. Alternatively, you can use the File | Publish menu item. Click on the Media icon situated on the left-most column of the Publish dialog box. The middle area is updated. Open the Select Type drop-down list. If you are on a Windows PC, choose Windows Executable (*.exe) and if you are using a Mac, choose MAC Executable (*.app). If needed, change the Project Title to encoderDemo_800. In the Folder field, make sure that the Chapter06/Publish folder still is the chosen value. Take some time to inspect the other options of the Publish dialog. One of them allows us to choose a custom icon for the generated .exe (Win) or .app (Mac) file. Leave the other options at their current value and click on the Publish button. When the publish process is complete, an information box will ask you if you want to see the generated output. Click on No to clear the information message and to close the Publish dialog. Now that the standalone application has been generated, we will use the Finder (Mac) or the Windows Explorer (Win) to take a look at the Chapter06/Publish folder. Use the Finder (Mac) or the Windows Explorer (Windows) to browse to the Chapter06/Publish folder of the exercises. Double-click on the encoderDemo_800.exe (Win) or on the encoderDemo_800.app (Mac) to open the generated application. Our Captivate movie opens as a standalone application in its own window. Notice that no browser is necessary to play the movie. This publish format is particularly useful when we want to burn the movie on a CD-ROM. When generating a Windows executable (.exe), Captivate can even generate an autorun.ini file so that the movie automatically plays when the CD-ROM is inserted in the computer.
Read more
  • 0
  • 0
  • 3911

article-image-article-enabling-plugin-internationalization
Packt
10 Aug 2012
5 min read
Save for later

Enabling Plugin Internationalization

Packt
10 Aug 2012
5 min read
In this article by Yannick Lefebvre, the author of WordPress Plugin Development Cookbook, we will learn about plugin localization through the following topics: Changing the WordPress language configuration Adapting default user settings for translation Making admin page code ready for translation Modifying shortcode output for translation Translating text strings using Poedit Loading a language file in the plugin initialization   Introduction WordPress is a worldwide phenomenon, with users embracing the platform all around the globe. To create a more specific experience for users in different locales, WordPress offers the ability to translate all of its user and visitor-facing content, resulting in numerous localizations becoming available for download online. Like most other functionalities in the platform, internationalization is also available to plugin developers through a set of easy-to-use functions. The main difference being that plugin translations are typically included with the extension, instead of being downloaded separately as is the case with WordPress. To prepare their plugin to be localized, developers must use special internationalization functions when dealing with text elements. Once this structure is in place, any user can create localizations by themselves for languages that they know and submit them back to the plugin author for inclusion in a future update to the extension. This article explains how to prepare a plugin to be translated and shows how to use the Poedit tool to create a new language file for a simple plugin. Changing the WordPress language configuration The first step to translating a plugin is to configure WordPress to a different language setting other than English. This will automatically trigger mechanisms in the platform to look for alternate language content for any internationalized string. In this recipe we will set the site to French. Getting ready You should have access to a WordPress development environment. How to do it... Navigate to the root of your WordPress installation. Open the file called wp-config.php in a code editor. Change the line that declares the site language from define('WPLANG', ''); to define('WPLANG', 'fr_FR');. Save and close the configuration file. How it works... Whenever WordPress renders a page for visitors or site administrators, it executes the contents of the wp-config.php file, which declares a number of site-wide constants. One of these constants is the site language. By default, this constant has no value, indicating that WordPress should display all content in U.S. English. If defined, the system tries to find a translation file under the wp-content/languages or wp-includes/languages directories of the site to locate translation strings for the target language. In this case, it will try to find a file called fr_FR.mo. While it will not actually find this file in a default installation, setting this configuration option will facilitate the creation and testing of a plugin translation file in later recipes. To learn more about translation files and find out where to download them from, visit the WordPress Codex available at http://codex.wordpress.org/WordPress_in_ Your_Language. Adapting default user settings for translation As mentioned in the introduction, plugin code needs to be specifically written to allow text items to be translated. This work starts in the plugin's activation routine, where default plugin option values are set, to find alternate values when a language other than English is specified in the site's configuration file. This recipe shows how to assign a translated string to a plugin's default options array on initialization. Getting ready You should have already followed the Changing the WordPress language configuration recipe to have a specified translation language for the site. How to do it... Navigate to the WordPress plugin directory of your development installation. Create a new directory called hello-world. Navigate to the directory and create a text file called hello-world.php. Open the new file in a code editor and add an appropriate header at the top of the plugin file, naming the plugin Hello World. Add the following line of code before the plugin's closing ?> PHP command to register a function to be called when the plugin is activated: code 1 Insert the following block of code to provide an implementation for the hw_set_default_options_array function: code 2 Save and close the plugin file. Navigate to the Plugins management page and activate the Hello World plugin. Using phpMyAdmin or the NetBeans IDE, find the options table entry where the option_name field has a value of hw_options to see the newly-created option. How it works... The __ function (that's two underscores) is a WordPress utility function that tries to find a translation for the text that it receives in its first argument, within the text domain specified in the second argument. A text domain is essentially a subsection of the global translation table that is managed by WordPress. In this example, the text to be translated is the string Hello World, for which the system tries to find a translation in the hw_hello_world domain. Since this domain is not available at this time, the function returns the original string that it received as its first parameter. The plugin code assigns the value it receives to the default configuration array. It should be noted that the __ function is actually an alias for the translate function. While both functions have the same functionality, using __ makes the code shorter when it contains a lot of text elements to be translated. While it may be tempting for developers to use a variable or constant in the first parameter of the __ function if they need to display the same text multiple times, this should not be done as it will cause problems with the translation lookup mechanism. See also Changing the WordPress language configuration recipe
Read more
  • 0
  • 0
  • 1890
article-image-blackboard-essentials-teachers-assignments-students
Packt
09 Aug 2012
4 min read
Save for later

Blackboard Essentials for Teachers - Assignments for Students

Packt
09 Aug 2012
4 min read
  About assignments An assignment is essentially an activity where the instructor tells the student, "Go do this, and then submit proof that you've done it". Optional features enable the instructor to supply the student with a file, to upload a file, and to submit both feedback and comments. Blackboard will create a link in the assignment, for the student to upload material to the instructor. Every assignment must have instructions and a student submission. The instructions are entered by the instructor when (s)he creates the assignment. The student submission can be material that the student types directly into the assignment-feedback form, or something that the student uploads (such as a word document or picture). The instructor can give a student feedback on the student's submission. In return, the student can give the instructor feedback on the assignment. Instructors can also allow multiple submissions, so the student has multiple tries to get it right. No matter how many trials the student takes, or how many files the student uploads, the instructor will give only one grade to the student. Adding an assignment To add an assignment to a Content Page, follow these steps: Select the Content Page to which you want to add an assignment. Select Create Assessment | Assignment. The Create Assignment page is displayed. Both the Name and the Instructions fields that you enter will be displayed on the page with the assignment, as shown in the following screenshot: In the preceding example, the instructor tells the student to download a file. You might want to remind the students to create a folder on their computers to hold all the material that they download from the course. Under Attached Files, you can add any files that you want the student to download and use in the assignment (this is optional). These can be files that you want the student to modify and then upload (such as a form to fill out), or files that contain instructions for an activity (such as instructions for performing an experiment), or source files that the student will use to create something (such as some raw video footage).If the student will complete the assignment while (s)he is online, enter the instructions into the Instructions area as shown earlier. If the student will complete the assignment while (s)he is offline, consider supplying the student with printer-friendly instructions that (s)he can download.Blackboard will allow the student to upload files up to 100 MB in size. The Grading and Availability sections contain standard options. If you enter Due Date for the assignment, it will not appear on the Content Page (see the preceding screenshot). However, it will appear in several other places. When the student enters the assignment, the due date will appear on the assignment page: The due date will also appear in the student's To Do block. Usually, the To Do block is added to the course's home page, and also to the student's home page. In the following screenshot, you can see the assignment in the To Do block of the course's home page. Because it was recently added, you can also see the assignment in the What's New block: And finally, Due Date will appear on the student's My Grades page: The due date has no effect on the availability of the assignment, or the student's grade. It is for informational purposes only. If you want Blackboard to limit the time period for which students can submit an assignment, use the Availability setting to make the assignment available only during a specified time. Under Recipients, determine if this assignment will be graded individually for each student, or for a group. Click on Submit to save your work. The assignment is added to the course. You don't need to do anything to make the assignment appear within the Assignments page and the To Do block. And, you can create a link to the assignment on the pages of your course.
Read more
  • 0
  • 0
  • 2218

article-image-mastering-newer-prezi-features
Packt
25 Jul 2012
10 min read
Save for later

Mastering the Newer Prezi Features

Packt
25 Jul 2012
10 min read
Templates There will always be time restraints put on us when building any business presentation. Mostly these will be pretty unrealistic time restraints as well. If you do find yourself against the clock when building a Prezi, then why not give yourself a slight advantage and use one of Prezi's templates to get your design started. There are lots of templates you can chose from and here's how to make the most out of them when the clock is ticking. The templates When you create any new Prezi online or in the desktop editor, you'll be presented with a choice of template as shown in the following screenshot: Before you decide which one to choose, you can explore them by simply selecting one and clicking the Preview button. You can see in the following screenshot that we've selected the Our Project template. Rolling your mouse over a template's thumbnail will show you some more details as well to help you choose. At the top of the screen, you'll see the options to either Start Editing or go Back to the templates screen. Before you make your choice, have a look around the template preview and check out all of the various objects available to you. Zoom in and out of certain areas that look interesting and use the arrows in the bottom right to go through the template's path and see how it flows. In the following screenshot, you can see that we've zoomed in to take a closer look at the assets included in this template: As you can see in the preceding screenshot, the Our Project template has some lovely assets included. The assets you'll be able to use in the template are images and sketches such as the Doodles that you can see in the top right of the screenshot. All of these assets can be moved around and used anywhere on your canvas. If you preview a template and decide it's the right one for you to use, then just click the Start Editing button to go into edit mode and begin building your Prezi. Getting the most from templates Once you go into edit mode, don't think that you're stuck with how everything is laid out. You can (and should) move things around to fit with the message you're trying to deliver to your audience. Paths The very first thing we'd suggest is clicking on the Paths button and taking a look at how the Prezi flows. The whole reason you're using a template is because you're pushed for time, but you should know how many frames you need and how many different areas you'll want to focus on in your presentation before you get started. If you do, then you can adjust the paths, add new path points, or delete some that are there already. Assets All of the templates, especially Our Project, will come with various assets included. Use them wherever you can. It'll save you lots of time searching for your own imagery if you can just move the existing assets around. As shown in the preceding screenshot, you are totally free to resize any asset in a template. Make the most of them and save yourself a whole heap of time. Branding The only down side of using templates is that they of course won't have any of your company colors, logo, or branding on them. This is easily fixed by using the Colors & Fonts|Theme Wizard found in the bubble menu. On the very first screen of the wizard, click the Replace Logo button to add your company logo. The logo must be a JPEG file no bigger than 250 pixels wide and 100 pixels high. Clicking the button will allow you to search for your logo and it will then be placed in the bottom left-hand corner of your Prezi at all times. On this screen, you can also change the background color of your entire canvas. On the next screen of the wizard, we recommend you switch to Manual mode by clicking the option in the bottom-left corner. In this screen, you can select the fonts to use in your Prezi. At the present time, Prezi still has only a limited number of fonts but we're confident you can find something close to the one your company uses. The reason we suggest switching to manual mode is because you'll be able to use your corporate colors for the fonts you select, and also on the frames and shapes within the Prezi. You'll need to know the RGB color values specified in your corporate branding. By using this final step, you'll get all the benefits of having an already designed Prezi without getting told off by your marketing team for going against their strict branding guidelines. Shapes A very simple element of the Prezi bubble menu which gets overlooked a lot is the InsertShapes| option. In this part of the article, we'll look at some things you may not have known about how shapes work within Prezi. Shortcut for shapes To quickly enter the Shapes menu when working in the Prezi canvas, just press the S key on your keyboard. Get creative In the first part of this chapter, we looked at the assets from a template called OurProject. Some of those assets were the line drawings shown below the male and female characters. When you see these "Doodles" as they're titled, you might think they've been drawn in some kind of graphics package and inserted into the Prezi canvas as you would anything else. On closer inspection in edit mode, you can see that each of the characters is actually made up of different lines from the Shapes menu. This is a great use of the line tool and we'd encourage you to try and create your own simple drawings wherever you can. These can then be reused over time, and will in turn save you lots of time searching for imagery via the Google image insert. Let's say that we want to add some more detail to the male character. Maybe we'll give him a more exciting hair style to replace the boring one that he has at the moment. First select the current hairline and delete it from the character's head. Now select the line tool from the Shapes menu and let's give this guy a flat top straight from the 80's. One of our lines is too long on the right. To adjust it, simply double-click to enter edit mode and drag the points to the right position as shown in the following screenshot: So there we have a great example of how to quickly draw your own image on the Prezi canvas by just using lines. It's an excellent feature of Prezi and as you can see, it's given our character a stunning new look. It's a shame his girlfriend doesn't think so too! Editing shapes In step three of giving our character a new haircut, you saw the edit menu which is accessed by a simple double-click. You can use the edit function on all items in the shapes menu apart from the Pencil and Highlighter tools. Any shape can be double-clicked to change its size and color as shown in the following screenshot. You can see that all of the shapes on the left have been copied and then edited to change their color and size. The edited versions on the right have all been double- clicked and one of the five extra available colors have been selected. The points of each shape have also been clicked on and dragged to change the dimensions of the shape. Holding the Shift key will not keep your shapes to scale. If you want to scale the shapes up or down, we recommend you use the transformation zebra by clicking the plus (+) or minus (-) signs. Editing lines When editing lines or arrows, you can change them from being straight to curved by dragging the center point in any direction. This is extremely useful when creating the line drawings we saw earlier. It's also useful to get arrows pointing at various objects on your canvas. Highlighter The highlighter tool from the shapes menu is extremely useful for pointing out key pieces of information like in the interesting fact shown in the following screenshot: Just drag it across the text you'd like to highlight. Once you've done that the highlighter marks become objects in their own right, so you can use the transformation zebra to change their size or position as shown in the following screenshot: Pencil The pencil tool can be used to draw freehand sketches like the one shown in the following screenshot. If you hadn't guessed it yet, our drawing is supposed to represent a brain which links to the interesting fact about ants. The pencil tool is great if you're good at sketching things out with your mouse. But if like us, your art skills need a little more work, you might want to stick to using the lines and shapes to create imagery! To change the color of your highlighter or pencil drawings, you will need to go into the Theme Wizard and edit the RGB values. This will help you keep things within your corporate branding guidelines again. Drawings and diagrams Another useful new feature and a big time saver within the Prezi insert menu are drawings and diagrams. You can locate the drawings and diagrams templates by clicking the button in-between YouTube and File from the Insert menu. There are twelve templates to choose from and each has been given a name that best describes their purpose. Rolling over each thumbnail will show you a little more detail to help you choose the right one. Once you have chosen, double-click the thumbnail and then decide where to place your drawing on the canvas. You can see in the following screenshot that the drawing or diagram is grouped together and will not become active until you click the green tick. Once you make the drawing active, you can access all of its frames, text, and any other elements that are included. In the following screenshot, you can see that we've zoomed into a section of the tree diagram. You can see in the preceding screenshot that the diagram uses lines, circular frames, and text which can all be edited in any way you like. This is the case for all of the diagrams and drawings available from the menu. Using these diagrams and drawings gives you a great chance to explain concepts and ideas to your colleagues with ease. You can see from the preceding screenshot that there's a good range of useful drawings and diagrams that you're used to seeing in business presentations. You can easily create organograms, timelines for projects, or business processes and cycles, simply by using the templates available and inserting your own content and imagery. By using the Theme wizard explained earlier in this chapter, you can make sure your drawings and diagrams use your corporate colors.
Read more
  • 0
  • 0
  • 2788
Modal Close icon
Modal Close icon