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
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7018 Articles
article-image-article-integrating-ios-features-using-monotouch
Packt
13 Dec 2011
10 min read
Save for later

Integrating iOS Features Using MonoTouch

Packt
13 Dec 2011
10 min read
(For more resources on this topic, see here.) Mobile devices offer a handful of features to the user. Creating an application that interacts with those features to provide a complete experience to users can surely be considered as an advantage. In this article, we will discuss some of the most common features of iOS and how to integrate some or all of their functionality to our applications. We will see how to offer the user the ability to make telephone calls and send SMS and e-mails, either by using the native platform applications, or by integrating the native user interface in our projects. Also, we will discuss the following components: MFMessageComposeViewController: This controller is suitable for sending text (SMS) messagesIntegrating iOS Features MFMailComposeViewController: This is the controller for sending e-mails with or without attachments ABAddressBook: This is the class that provides us access to the address book database ABPersonViewController: This is the controller that displays and/or edits contact information from the address book EKEventStore: This is the class that is responsible for managing calendar events Furthermore, we will learn how to read and save contact information, how to display contact details, and interact with the device calendar. Note that some of the examples in this article will require a device. For example, the simulator does not contain the messaging application. To deploy to a device, you will need to enroll as an iOS Developer through Apple's Developer Portal and obtain a commercial license of MonoTouch. Starting phone calls In this recipe, we will learn how to invoke the native phone application to allow the user to place a call. Getting ready Create a new project in MonoDevelop, and name it PhoneCallApp. The native phone application is not available on the simulator. It is only available on an iPhone device. How to do it... Add a button on the view of MainController, and override the ViewDidLoad method. Implement it with the following code. Replace the number with a real phone number, if you actually want the call to be placed: this.buttonCall.TouchUpInside += delegate {  NSUrl url = new NSUrl("tel:+123456789012");  if (UIApplication.SharedApplication.CanOpenUrl(url)){    UIApplication.SharedApplication.OpenUrl(url);  }  else{    Console.WriteLine("Cannot open url: {0}", url.AbsoluteString);  }} ; Compile and run the application on the device. Tap the Call! button to start the call. The following screenshot shows the phone application placing a call: How it works... Through the UIApplication.SharedApplication static property, we have access to the application's UIApplication object. We can use its OpenUrl method, which accepts an NSUrl variable to initiate a call: UIApplication.SharedApplication.OpenUrl(url); Since not all iOS devices support the native phone application, it would be useful to check for availability frst: if (UIApplication.SharedApplication.CanOpenUrl(url))   When the OpenUrl method is called, the native phone application will be executed, and it will start calling the number immediately. Note that the tel: prefx is needed to initiate the call. There's more... MonoTouch also supports the CoreTelephony framework, through the MonoTouch. CoreTelephony namespace. This is a simple framework that provides information on call state, connection, carrier info, and so on. Note that when a call starts, the native phone application enters into the foreground, causing the application to be suspended. The following is a simple usage of the CoreTelephony framework: CTCallCenter callCenter = new CTCallCenter();callCenter.CallEventHandler = delegate(CTCall call) {  Console.WriteLine(call.CallState);} ;   Note that the handler is assigned with an equals sign (=) instead of the common plus-equals (+=) combination. This is because CallEventHandler is a property and not an event. When the application enters into the background, events are not distributed to it. Only the last occured event will be distributed when the application returns to the foreground. More info on OpenUrl The OpenUrl method can be used to open various native and non-native applications. For example, to open a web page in Safari, just create an NSUrl object with the following link: NSUrl url = new NSUrl("http://www.packtpub.com");   See also In this article: Sending text messages and e-mails Sending text messages and e-mails In this recipe, we will learn how to invoke the native mail and messaging applications within our own application. Getting ready Create a new project in MonoDevelop, and name it SendTextApp. How to do it... Add two buttons on the main view of MainController. Override the ViewDidLoad method of the MainController class, and implement it with the following code: this.buttonSendText.TouchUpInside += delegate {  NSUrl textUrl = new NSUrl("sms:");  if (UIApplication.SharedApplication.CanOpenUrl(textUrl)){    UIApplication.SharedApplication.OpenUrl(textUrl);  } else{    Console.WriteLine("Cannot send text message!");  }} ;this.buttonSendEmail.TouchUpInside += delegate {  NSUrl emailUrl = new NSUrl("mailto:");  if (UIApplication.SharedApplication.CanOpenUrl(emailUrl)){    UIApplication.SharedApplication.OpenUrl(emailUrl);  } else{    Console.WriteLine("Cannot send e-mail message!");  }} ; Compile and run the application on the device. Tap on one of the buttons to open the corresponding application. How it works... Once again, using the OpenUrl method, we can send text or e-mail messages. In this example code, just using the sms: prefx will open the native text messaging application. Adding a cell phone number after the sms: prefx will open the native messaging application: UIApplication.SharedApplication.OpenUrl(new NSUrl("sms:+123456789012"));     Apart from the recipient number, there is no other data that can be set before the native text message application is displayed. For opening the native e-mail application, the process is similar. Passing the mailto: prefx opens the edit mail controller. UIApplication.SharedApplication.OpenUrl(new NSUrl("mailto:"));     The mailto: url scheme supports various parameters for customizing an e-mail message. These parameters allows us to enter sender address, subject, and message: UIApplication.SharedApplication.OpenUrl("mailto:recipient@example.com?subject=Email%20with%20MonoTouch!&body=This%20is%20the%20message%20body!"); There's more... Although iOS provides access to opening the native messaging applications, pre-defning message content in the case of e-mails, this is where the control from inside the application stops. There is no way of actually sending the message through code. It is the user that will decide whether to send the message or not. More info on opening external applications The OpenUrl method provides an interface for opening the native messaging applications. Opening external applications has one drawback: the application that calls the OpenUrl method transitions to the background. Up to iOS version 3.*, this was the only way of providing messaging through an application. Since iOS version 4.0, Apple has provided the messaging controllers to the SDK. The following recipes discuss their usage. See also In this article: Starting phone calls Using text messaging in our application Using text messaging in our application In this recipe, we will learn how to provide text messaging functionality within our application using the native messaging user interface. Getting ready Create a new project in MonoDevelop, and name it TextMessageApp. How to do it... Add a button on the view of MainController. Enter the following using directive in the MainController.cs fle: using MonoTouch.MessageUI; Implement the ViewDidLoad method with the following code, changing the recipient number and/or the message body at your discretion: private MFMessageComposeViewController messageController;public override void ViewDidLoad (){  base.ViewDidLoad ();  this.buttonSendMessage.TouchUpInside += delegate {    if (MFMessageComposeViewController.CanSendText){      this.messageController = new          MFMessageComposeViewController();      this.messageController.Recipients = new          string[] { "+123456789012" };      this.messageController.Body = "Text from MonoTouch";      this.messageController.MessageComposeDelegate =          new MessageComposerDelegate();      this.PresentModalViewController(         this.messageController, true);    } else{      Console.WriteLine("Cannot send text message!");    }  } ;} Add the following nested class: private class MessageComposerDelegate :    MFMessageComposeViewControllerDelegate{  public override void Finished (MFMessageComposeViewController     controller, MessageComposeResult result){    switch (result){      case MessageComposeResult.Sent:        Console.WriteLine("Message sent!");      break;      case MessageComposeResult.Cancelled:        Console.WriteLine("Message cancelled!");      break;      default:        Console.WriteLine("Message sending failed!");      break;    }    controller.DismissModalViewControllerAnimated(true);  }} Compile and run the application on the device. Tap the Send message button to open the message controller. Tap the Send button to send the message, or the Cancel button to return to the application. How it works... The MonoTouch.MessageUI namespace contains the necessary UI elements that allow us to implement messaging in an iOS application. For text messaging (SMS), we need the MFMessageComposeViewController class. Only the iPhone is capable of sending text messages out of the box. With iOS 5, both the iPod and the iPad can send text messages, but the user might not have enabled this feature on the device. For this reason, checking for availability is the best practice. The MFMessageComposeViewController class contains a static method, named CanSendText, which returns a boolean value indicating whether we can use this functionality. The important thing in this case is that we should check if sending text messages is available prior to initializing the controller. This is because when you try to initialize the controller on a device that does not support text messaging, or the simulator, you will get the following message on the screen:   To determine when the user has taken action in the message UI, we implement a Delegate object and override the Finished method: private class MessageComposerDelegate :    MFMessageComposeViewControllerDelegate   Another option, provided by MonoTouch, is to subscribe to the Finished event of the MFMessageComposeViewController class. Inside the Finished method, we can provide functionality according to the MessageComposeResult parameter. Its value can be one of the following three: Sent: This value indicates that the message was sent successfully Cancelled: This value indicates that the user has tapped the Cancel button, and the message will not be sent Failed: This value indicates that message sending failed The last thing to do is to dismiss the message controller, which is done as follows: controller.DismissModalViewControllerAnimated(true);   After initializing the controller, we can set the recipients and body message to the appropriate properties: this.messageController.Recipients = new string[] { "+123456789012" };this.messageController.Body = "Text from MonoTouch";   The Recipients property accepts a string array that allows for multiple recipient numbers. You may have noticed that the Delegate object for the message controller is set to its MessageComposeDelegate property, instead of the common Delegate. This is because the MFMessageComposeViewController class directly inherits from the UINavigationController class, so the Delegate property accepts values of the type UINavigationControllerDelegate. There's more... The fact that the SDK provides the user interface to send text messages does not mean that it is customizable. Just like invoking the native messaging application, it is the user who will decide whether to send the message or discard it. In fact, after the controller is presented on the screen, any attempts to change the actual object or any of its properties will simply fail. Furthermore, the user can change or delete both the recipient and the message body. The real beneft though is that the messaging user interface is displayed within our application, instead of running separately. SMS only The MFMessageComposeViewController can only be used for sending Short Message Service (SMS) messages and not Multimedia Messaging Service (MMS).
Read more
  • 0
  • 0
  • 3561

article-image-wordpress-3-designing-your-blog
Packt
12 Dec 2011
19 min read
Save for later

WordPress 3: Designing your Blog

Packt
12 Dec 2011
19 min read
(For more resources on WordPress, see here.) Blog design principles Blogs tend to have a fairly simple, minimalist layout and design. This has always been one of their key characteristics. Blogs are all about frequently updated content, so the main purpose of their design is to present that content as efficiently and conveniently as possible. The vast majority of blogs present their most recent content on the page that visitors arrive at; hence, the front page contains the latest posts. There's no home page with a verbose welcome message and a long navigation menu to click through to the important stuff. The visitor gets straight into the meat of the blog. By default, this is the structure that WordPress provides. It is possible to set a static page as your blog's front page, but, in the vast majority of cases, I wouldn't recommend it. So when considering the architecture of a blog, unlike other types of website, we don't have to worry too much about a complex navigation structure. There is a convention that we can follow. Yes, we may want to add some extra static pages, but probably only a few of these. What we are most concerned with in blog design is not a complicated navigation structure and how all the pages link together, but how the actual blog page should look and feel. This can be broken down into four key components, which we will examine, one by one: Layout Color Typography Usability and accessibility Layout Good design is all about making something easy for people to use. Designers achieve this by employing standards and conventions. For example, cars have a standard design: four wheels, a chassis, a steering wheel, gas pedal, brake, gear shift, and so on. Car designers have stuck to this convention for many years. First, because it works well and second, because it enables us to drive any car we choose. When you sit down in any standard road car, you know how it works. You turn the key in the ignition, select a gear, hit the gas, and off you go. It's certainly not beyond the ken of car designers to come up with new ways for getting a car in motion (a joystick maybe, or a hand-operated brake) but this would make it more difficult for people to drive. Cars work reasonably safely and efficiently because we are all familiar with these conventions. The layout of blog pages also tends to follow certain conventions. As with cars, this helps people to use blogs efficiently. They know how they work, because they're familiar with the conventions. Most blogs have a header and a footer with the main content arranged into columns. This columnar layout works very well for the type of chronological content presented in blogs. Because of these conventions, the decisions about our blog layout are fairly simple. It's basically a case of deciding where we want to place all our page elements and content within this standard columnar layout. The set of page elements we have to choose from is also based on fairly well entrenched blogging conventions. The list of things we may want on our page includes: Header Posts Comments Static content (for example, the About page) Links to static pages (simple navigation) RSS feeds Search Categories Archives Blogroll Widgets and plugins Footer If we look at this list in more detail, we can see that these page elements can be grouped in a sensible way. For example: Group 1 Header Links to static pages Group 2 Posts Comments Static content Group 3 RSS Feeds Search Categories Group 4 Archives Blogroll Widgets and plugins Group 5 Footer This isn't the only possible grouping scheme we might come up with. For example, we may place the items in Groups 3 and 4 into a single larger group, or we may have widgets and plugins in a group on their own. From this grouping, we can see that the type of items in Group 2 are likely to be the main content on our page, with Groups 3 and 4 being placed in sidebars . Sidebars are areas on the page where we place ancillary content. Having considered the elements we want on the page and how they might be grouped, we can think about possible layouts. Within the conventional columnar structure of blogs there are quite a few possible layout variations. We'll look at four of the most common. The first is a three-column layout. Here, we have two sidebars, one on either side of the main content. Using this type of layout, we would probably place the items in Groups 3 and 4 in the sidebars and Group 2 in the main content area. A variation on the three-column layout is to have the two sidebars next to each other on one side of the page (usually the right), as shown in the following diagram. This is a popular layout for blogs, not just for aesthetics, but because the search engine spiders encounter the post column first as that content is at the top of the template. Using two sidebars is useful if you anticipate having a lot of ancillary content on your blog. The list of page elements given earlier is really the bare minimum you would want on your page. However, if you decide to use lots of widgets or have a long blogroll, it's a good idea to spread them across two sidebars. This means that more of your content can be placed above the fold. The concept of above the fold in web design applies to content in a web page which is visible without having to scroll down, that is, the stuff in the top part of the page. It's a good idea to place the most important content above the fold so that readers can see it immediately. This is particularly true if you plan to monetize your blog by displaying adverts. Adverts that appear above the fold get the most exposure, and therefore, generate the most revenue Another popular layout amongst bloggers has just two columns. In this layout, we would place the items in Groups 3 and 4 together in the one sidebar. It doesn't really matter which side of the page the sidebar is placed, but it seems more common to have it on the right. Studies have shown that a web user's eyes are most often focused on the top-left region of a web page, when they first open any page. So it makes sense to place your main content there, with your sidebar on the right. Also, remember that the search engine spiders will find the leftmost content first. You want them to find your main content quickly, which is a good reason for placing your sidebar on the right, out of their way. An important benefit of a two-column layout is that it allows more room for your main content area. This may be important, if you intend to use a lot of video or images within your blog posts. The extra room allows you to display this visual content bigger. Many blogs place some of their ancillary content just above the footer, below the main content. This also has the advantage of leaving more space for the main content, as with the two-column layout. The following diagram shows this type of layout. Here, the content just above the footer isn't strictly speaking a sidebar, but I've labeled it this way because it's the terminology most often applied to this type of ancillary content. Wireframing The layout diagrams we've just seen are referred to as wireframes by web designers. They give a simple overview of where the elements of a page should be placed. It would be a good idea for you to create your own wireframe for your blog design. This can be done using most graphic software packages or something like Microsoft Visio , or a simple pen and paper does the job equally well! Color This is the next design principle we need to consider. It may be that you already have a corporate color scheme based on your company logo, stationery, or existing website. In this case, you'll probably want to continue that theme through your blog design. Even if you already have your corporate color scheme, this section may still be useful in case you decide to change your blog colors in the future. The subject of color in design is a large one. Design students spend a great deal of time learning about the psychology and science of colors and techniques for achieving the best color schemes. Obviously, we don't have enough space to go into that kind of detail, but I will try to give you a few pointers. The first thing to think about is the psychology of color, in particular, color associations. This is the idea that different colors evoke different feelings and emotions in the eye of the beholder. To a certain extent this can be rather subjective and it can also depend on cultural influences, but there are some generalities that can be applied. For example, red is often perceived as being exciting, passionate, or dramatic. Yellow is an active and highly visible color, which is why it is used in warning signs. It is also associated with energy and happiness. Blue is sometimes thought of as being cold. It can also be a calming color and may sometimes be seen as corporate or conservative. White, for many people, gives the idea of cleanliness, purity, and perfection. Black can be seen as strong, elegant, and chic. Obviously, these color associations can vary from person to person, so designers don't rely on them solely in their color decisions, but they are certainly worth bearing in mind. There are more practical considerations regarding color that are probably more relevant than color psychology. For example, we all know that some color combinations don't work well together. There is a great deal of design theory aimed at devising good color combinations, but unless you're a professional designer, it's not really worth going into. Probably the best method for working out good color combinations is trial and error. If you're trying to figure out a background color and text color for your blog, simply test a few out. You could use a graphics package such as Photoshop or Microsoft Paint , or one of the many online color tools such as, http://colorschemedesigner.com/ or Adobe's Kuler at http://kuler.adobe.com. When choosing background and text colors you need to think about contrast. For example, yellow text on a white background can be very difficult to read. Some people also find light text on a black background a strain on their eyes. It's also important not to use too many colors in your design. Try to limit your palette to a maximum of three or four. Sometimes you may only need two colors to make an attractive design. One method for devising color combinations is to look for examples all around you, particularly in nature. Maybe look at a photograph of a landscape and pick out color combinations you like. Also consider the work of professional designers. Think about websites and blogs you like, and examine the color schemes they have used. You will also find good examples in offline design—pick up a book and see how colors have been used in the cover design. If you would like to base your blog's color scheme on your company logo, you could use lighter and darker versions of one color from the logo. Use the most vivid color in the logo for emphasis or headings. Web color theory At this point, it's worth looking at the technical theory behind colors on the Web. Web browsers use the Hexadecimal RGB color system to render colors in web pages. This is because computer monitors use an RGB color model, which means every pixel is colored using a combination of red, green, and blue light (hence RGB). There are 256 different levels of red light, 256 different levels of green light, and 256 different levels of blue light. These can be combined to create 16,277,216 different colors, which are all available for your web browser. The hexadecimal system gives us a way of counting from 0 to 255 using numbers and letters, which covers all 256 levels of RGB light. In the hexadecimal scale, 0 is 00 and 255 is FF. A six-character hexadecimal color code specifies the levels of red, green and blue, which form a particular color. For example, the color white combines red, green, and blue at their highest possible levels, that is 255. Remember that in hexadecimal 255 is FF, so the color code for white is FFFFFF (Red: FF, Green: FF, and Blue: FF). The color code for black is 000000 as the levels of red, green, and blue are set to their lowest, or 00 (in hexadecimal). The code for red is FF0000, blue is 0000FF, and yellow is FFFF00, and so on. We can use six-character Hexadecimal RGB codes to define all of the 16,277,216 web colors. So how do we know the hexadecimal code for a particular color? Well, there are many tools available that define the Hexadecimal RGB codes for the colors you choose. Some are standalone applications for PC or Mac, and others are online. Take a look at https://www.webpagefx.com/web-design/color-picker/ or do a quick search in Google on color picker . For more information on web colors , read the article at http://en.wikipedia.org/wiki/Web_colors. Typography Another important consideration for your blog design is the fonts you use. Your choice of font will have a big impact on the readability of your blog. It's important to bear in mind that although there are literally thousands of fonts to choose from, only a small number of them are practical for web design. This is because a web browser can only display fonts that are already installed on the user's computer. If you choose an obscure font for your blog, the chances are that most users won't have it installed on their computer. If this is the case the web browser will automatically select a substitute font. This may be smaller or far less readable than the font you had in mind. It's always safest to stick to the fonts that are commonly used in web design, which are known as web safe fonts. These include the following: Arial Verdana Times New Roman Georgia There are two types of font, serif and sans-serif. Serif fonts have little flourishes at the end of the strokes whereas sans-serif fonts don't have this extra decoration. Arial and Verdana are sans-serif fonts, whereas Times New Roman and Georgia are serif fonts. As you'll see later in the article, when we look at CSS, fonts are usually specified in groups or families. They are listed in the order of the designer's preference. For example, a designer may specify font-family:"Georgia, Times New Roman, serif". This means when the browser renders the page it will first look for the Georgia font; if it isn't installed, it will look for the Times New Roman font and if that isn't installed, it will look for the computer's default serif font. This method gives the designer more control over the font choices the browser will make. The size of your font is also an important factor. Generally speaking, the bigger it is, the easier it is to read. Computer displays are getting bigger and bigger but the default screen resolutions are tending to get smaller. In other words, the individual pixels on users' screens are getting smaller. This is a good reason for web designers to choose larger font sizes. This trend can be seen on many Web 2.0 sites, which tend to use large and clear fonts as part of their design, for example http://www.37signals.com. But be careful not to go too big as this can make your design look messy and a little childish. Remember that you're not limited to using just one font in your blog design. For example, you may decide to use a different font for your headings. This can be an effective design feature but don't go crazy by using too many fonts, as this will make your design look messy. Probably two, or at most three, fonts on a page are plenty. Font replacement Font replacement refers to a relatively new group of technologies that are pushing the envelope of web typography. In theory, they allow designers to use any font in their web page designs. In practice, things are a little more complicated. Issues around browser compatibility and font licensing make font replacement technologies a bit of a minefield for anyone who is new to web design. It's true that, thanks to font replacement technologies, professional designers are no longer constrained by the notion of web safe fonts. But, if you are a web design novice, I recommend you stick to web safe fonts until your skills improve and you are ready to learn a whole new technology. A full discussion on font replacement is way beyond the scope of this article; I mention it only to give you a better overview of the current state of web typography. But if you are interested in knowing more, three popular font replacement technologies are Cufón (http://cufon.shoqolate.com), Font Squirrel (http://www.fontsquirrel.com), and Google Fonts API (http://code.google.com/apis/webfonts/). There is also something known as @font-face, which is part of CSS3, the latest specification of CSS. Again, it offers the tantalizing possibility of giving designers free rein in their choice of fonts. Sadly, @font-face is also hindered by browser compatibility and font licensing issues. The Font Squirrel technology, mentioned previously, resolves these issues to a certain extent, so this is something to be aware of as your web design skills develop. But for the time being, I recommend you concentrate on the basics of web typography and don't worry about @font-face until you feel ready. Usability and accessibility This is another very important area to consider when designing your blog. Many people, who live with various disabilities, use a range of 'assistive' software to access the Web. For example, people with visual impairments use screen readers, which translate the text in a web browser into audible speech. There are also people who are unable to use a mouse, and instead rely on their keyboard to access web pages. It's the responsibility of web designers to ensure that their websites are accessible for these different methods of browsing. There's no sense in alienating this group of web surfers just because your blog is inaccessible to them. There are also many other circumstances when your blog might be accessed by means other than a standard web browser, for example, via mobile phones, PDAs, or tablets. Again, a good designer will ensure that these modes of browsing are catered for. The web design industry has been well aware of these accessibility issues for many years and has come up with guidelines and technologies to help conscientious designers build websites that are standards compliant . These web standards help ensure best practice and maximize accessibility and usability. Luckily, WordPress takes care of a lot of the accessibility issues simply by the way it's been developed and built. The code behind WordPress is valid XHTML and CSS, which means that it complies with web standards and is easily accessible. It's important, then, that you don't break the system by allowing bad practice to creep in. Some of the things to bear in mind relate to a couple of design principles we've already discussed, for example, using a color scheme and font size that makes your text easy to read. Other issues include keeping the number of navigation links on your page to a minimum—a whole load of useless links can be annoying for people who have to tab through them to get to your main content. You should also ensure that any third-party plugins you install are standards-compliant and don't throw up any accessibility problems. The same is true if you decide to use a ready-made theme for your blog design. Just make sure it's accessible and satisfies web standards. For more background reading on web standards, you could take a look at http://www.alistapart.com or the World Wide Web Consortium (W3C) website at http://www.w3.org. Implementing your blog design We've now considered the principles involved in designing our blog. The next thing to decide is how we actually carry out the design work. There are three main options available, each of which involves varying degrees of work. However, they all require knowledge of the design principles we just covered. The first approach is probably the easiest; it simply involves finding a readymade theme and installing it in WordPress. By working through the earlier design principles, you should have an idea of what you want your blog to look like and then you simply need to find a theme that matches your vision as closely as possible. A good place to start looking is the official WordPress Free Themes Directory at http://wordpress.org/extend/themes/. You'll also find many more theme resources by running a search through Google. There are hundreds of very attractive WordPress themes available for free and many others which you can pay for. However, if you adopt this approach to your blog design, you won't have a unique or original blog. The chances are the theme you choose will also be seen on many other blogs. At the other end of the scale, in terms of workload, is designing your own theme from scratch. This is a fairly complicated and technical process, and is well beyond the scope of this article. In fact, it's a subject that requires its own book. If you intend to build your own theme, I recommend WordPress 2.8 Theme Design by Tessa Blakeley Silver ISBN 978-1-849510-08-0 published by Packt Publishing. The third approach is to modify a readymade theme. You could do this with any theme you choose, even the default Twenty Ten theme that ships with WordPress. However, if you edit a fully developed theme, you spend a lot of time unpicking someone else's design work and you may still be left with elements that are not completely your own. A better method is to start with a theme framework, which has been specially designed to be a blank canvas for your own design. Over the last few years many WordPress theme frameworks have appeared, some free, some paid-for. Two of the most popular paid-for theme frameworks are Thesis (http://diythemes.com/) and Genesis (http://www.studiopress.com/themes/genesis), while popular free frameworks include Hybrid (http://themehybrid.com/), Carrington (http://carringtontheme.com/), and Thematic (see below).
Read more
  • 0
  • 0
  • 2647

article-image-configuring-your-moodle-course
Packt
12 Dec 2011
7 min read
Save for later

Configuring your Moodle Course

Packt
12 Dec 2011
7 min read
(For more resources on Moodle, see here.) From curriculum to courses: What counts as a Moodle course Let's start this section with me describing the course I'm going to be converting to Moodle as we work together through this book. The course is called "Backyard Ballistics" and it's a science course that forms part of an applied physics qualification. The course is all about the art of firing weird objects through the air with chemicals and equipment that you will find in your average domestic kitchen and garden shed.   There are certain aspects of this course that I can't convert to Moodle. I want my students to get an appreciation of energy and dynamics by "doing" (kinesthetic learning) the science using everyday items you'll find around your house. But there is a good deal of support material, handouts, diagrams, and quizzes, that currently I try and distribute electronically using a "shared drive" on the college server. However, my students can never find the materials I tell them to go and look for. At least, that's their excuse. But I've got to admit that after a few years of use our shared drive is starting to look a bit of a mess. But where do I put these resources in Moodle? The answer is that you put them into a Moodle course. And here is a screenshot of just a fragment of a Moodle course: (Move the mouse over the image to enlarge.) I've divided my course into six topics: Getting Things Flying ‹ Lighter Than Air: Hydrogen Filled Balloons Fire Kites ‹ Basic Rocketry: The Match Rocket ‹ The World Famous Tennis Ball Mortar! ‹ Backyard Ballistics: End of Course Project The reason why I've chosen to convert Backyard Ballistics into topics is partly because that's how I teach it and partly because I am happy for the students to "dip into" the resources and activities I have converted to Moodle. Before we look at how we can get a course and start adding content to it we really need to understand what Moodle considers to be a course and how Moodle organizes them. What is a Moodle course You can clearly see now that, at its most basic, a Moodle course is a placeholder for resources and activities. Obviously it's much more than this, as you'll be learning as you work through this book. One obvious advantage Moodle has over a shared drive is that links to resources and activities can be interspersed with text and graphics to make the experience more visually appealing and engaging, and the resources I upload easy to find (I don't accept any excuses these days). How Moodle organizes its courses Let's take a quick look at how you can organize courses in Moodle. To help organize courses, Moodle has the idea of categories and subcategories: Remember that you'll only find resources and activities in a Moodle course. Categories and subcategories are only there to help you organize and manage the organization of courses. So how does that work in practice? For example, I work in the Physics department, part of the Faculty of Science. My Backyard Ballistics course supports the Applied Physics qualification. Here's how we've got our categories and subcategories arranged: I'm sure you could think of examples for your subject area. You could have a category called English that contained two subcategories, Literature and Language. Within literature you could have short courses on particular aspects of the set text you are teaching. You could have a category 20th Century History containing subcategories for Britain, Germany, France, Italy, and USA. Each country subcategory can contain further subcategories called Politics, Society, and so on. Because this is such a key issue when you first start using Moodle, let's spend a little time investigating the more common approaches taken when converting face-to-face teaching to Moodle. Breaking up is hard to do How you break up a face-to-face, traditionally taught course, depends on the age group and the subject area you are working in, so let's study some examples. Often younger children will have the same teacher for all of their subjects. Schools in this situation usually categorize Moodle courses based on year groups, and within the year group each teacher will have their own subcategory in which they are free to create and delete courses as they wish: Each teacher having their own Moodle course means it is much easier for the children to find the resources that have been uploaded and activities created for them. As the children get older you can start running different Moodle courses for different subjects depending on that child's age and ability. Now I could have a category for each year group, and within them categories for each subject area: Instead of a mathematics teacher having just one course they may instead have a course in Year 9, two in Year 10 and another one in Year 12. As the subject areas begin to broaden and the amount of material you need to get through increases, you might need to think about having Moodle courses for particular subject areas, especially those areas that students tend to struggle with. As students become older, things tend to become easier, because qualifications examined by external examination bodies will have their own syllabus. Read the syllabus carefully and you will often be able to see immediately how to break the subject down into Moodle courses. Mathematics, for example, naturally falls into categories, namely: ‹ Number ‹ Algebra Geometry (shape, space, and measure) ‹ Data handling and statistics Within each category there is then a natural divide between subject areas. See whether you can spot a similar pattern in your subject area. For students who are older still (that is, college or university age), subjects are most often taught in units anyway. A short 10-week unit, for example, is an ideal candidate for a Moodle course. To close this section, I will leave you with just a few more thoughts. One is that Moodle courses can also be created to develop a student's key skills. Examples of key skills could be: Communication ‹ Application of number ‹ Information and communication technology ‹ Problem solving ‹ Collaboration Another is that Moodle courses are not set in stone; once they are created they can be changed as you require. You will also see later in this book that responsibility for different aspects of your Moodle course can be delegated down to your students, enabling you all to work together developing your page. Have a go hero – developing key skills Try identifying courses that support developing one of the key skills. If key skills are a priority in your school or college, then no doubt you will have lots of skills-based teaching materials already to hand that you can convert into Moodle courses. If in doubt, hold a meeting In this section we've been investigating how we could break up traditionally taught, face-to- face courses and identifying what might be converted into Moodle courses. You can do this along traditional lines, or you can approach the problem by looking at key skills or learning styles. It is an extremely complicated issue and will undoubtedly involve discussions with your department colleagues. I strongly suggest you hold a Moodle meeting to discuss which courses are going to be created, initially. Use the opportunity to discuss who is going to teach them, and what categories they are going to ft into. Plan as much as you can before you start doing anything in Moodle. Remember to involve your Moodle administrator in those meetings, especially if they are the one responsible for creating your categories and courses. Now that we know what Moodle categories and courses we're going to need, we can focus on creating and running those courses. Let's get started: Setting up the course The remainder of the book will focus on just one course. If you're putting your whole department into Moodle then you'll have lots of courses to work through. That's why it's so useful to assign other teaching staff to course creation, and let them share the work. We'll show you how to do that too.
Read more
  • 0
  • 0
  • 2215

article-image-building-your-first-liferay-site
Packt
09 Dec 2011
10 min read
Save for later

Building your First Liferay Site

Packt
09 Dec 2011
10 min read
(For more resources on Liferay, see here.) Designing the site—Painting the full picture Whenever we get the requirements of the portal, we should first ask ourselves, how would the portal look when it goes live? This one small question will open a door to a lot of other questions and a lot of information which will be required to implement the portal. You should always think of the end state of the portal and then start painting the complete picture of the portal. This approach is known as Beginning with the end! Now, as we have just discussed the approach we should take while starting the site design, let's understand what all information we can retrieve or get when we ask this question to ourselves. We will discuss about four main components of the Liferay Portal design. Users No matter what the size of the portal is—small, medium, or large—it will always be designed for the users. Users are in the centre of any portal application. Let's think of a very common portal . Just imagine that you have to implement this portal. You are sitting in your nice comfy rocking chair and thinking of the users of this portal. What all questions would you ask yourself (or the client, if he/she is with you) about the users of this portal? Who will be using this portal? Will all the users of this portal have same privileges? Or some of the users will have more privileges than the others? Can we collect the users into any specific group? Are these users organized in any kind of hierarchy? Can the users leave or join this portal at a will? and so on. Let's discuss about the answers of the preceding questions and the information we can retrieve from the answers. If we want to provide an answer to the first question in only one word, then it can be—Users. It is quite obvious that the portal will be used by the users. However, if we go into the detail of this question we can get an answer like—all the employees of CNN, users from all over the world, John Walter who will be responsible for administration of the entire portal, and so on. So answer to this question will give us the information about all the players associated with the portal. If all the users of the portal have the same privileges, then it's pretty obvious that every user will be able to perform the same function in the portal. However, this may not be the case with our portal, http://www.cnn.com. Here, we have end users who will come to the portal and will access the information; we can also have a group of internal users who can create the content. Similarly, there can be a group who can approve the content and other group can publish the content; there can also be users who are responsible for user management and one or more users who are responsible for portal management. So this kind of question will give us the information about different roles and permissions associated with each role in our portal. It will also give us the information that which user should be associated with what kind of role. This information is very useful when we are working on the security piece of the portal. If the answer of the third question is Yes then we can either create a user group in our portal or group the users into a specific role. This question will give us the information about user grouping in the portal. Now, answer to the last two questions will be discussed in more detail in this article. However, these questions will help us to determine if we should use an organization or community or mix of both in our portal. Every Liferay portal must have at least one organization or community. Once we get the information about the users in our portal, we should think of the content next. Content No portal can exist without any kind of content. The content can be a static HTML, a static article, a video, an audio, podcast, document, image, and so on. To make the portal more effective, we have to manage the content properly. We will continue with our example of : What kind of questions can we ask to ourselves or to the client about the content? What are the types of the content we will use in the portal? Where are we going to store the content? To Liferay database or some other external database? Do we have to create the content from scratch? Do we need to migrate existing content to Liferay? And a few more… I am sure you must be visiting many portals every day. Can you think of the possible answers to the preceding questions? Also, think of the information which can be retrieved from those answers. The answer to the first question can be—document, images, web content, video, podcast, and so on. This answer will give us an idea about the content types which need to be implemented in the portal. Some of the contents like web content and documents can be available out of the box in Liferay; while other content types like video and podcast may not be available out of the box. This information will enable us to determine the types of content and effort required to create the new content. The second question is a bit tricky. By default, Liferay stores the content into database. However, if the client wants we can store the content in some shared location as well. For example, storing documents into file system. Also, it requires high availability. You can refer to wiki about this on . An answer to this question will give us information like if we need to add any additional hardware or not, if we should do any specific configuration to meet the requirements, and so on. Answers to third and fourth questions will be mainly used for the effort estimation purpose. If a portal like site is using a huge amount of content and all of the content has to be built from scratch then it may take a good amount of time. If the content is already available, we need to consider the effort of migrating and organizing the content. We can also think of other questions like requirement of workflow, type of the flow, if staging is required for the content or not, and so on. All of the preceding questions will give us a good picture about the content to be created or used in our portal. Once we are thorough with this section, it becomes easy to appoint someone to do content management design for your portal. Applications We have discussed about the user and the content of the portal. However, what about the applications which will be hosted on the portal? We cannot imagine a portal without any application nowadays. A portal can contain different applications like forum, wiki, blog, document viewer, video player, and so on. Let's get a list of questions which you should ask yourself while designing the portal: What are the different applications required for this portal? Do we have any application available out of the box in Liferay? Do we need to modify/extend any existing application available in Liferay? Do we have to create any new application for the portal? If yes, what is the complexity of this application? Liferay ships with more than 60 applications pre-bundled known as portlets. These applications are very commonly used in many of the portals. When we ask the preceding questions to ourselves, we get the following information: Number of applications required in the portal How many applications are available out of the box? If we have more applications available OOTB (out of the box) then it can reduce the development time Scope of the project. Do we need any integration with external system or not? Kind of applications we have to develop from scratch Once we go through the preceding set of questions, it becomes very easy to get a picture of the applications required in our portal. It will also provide us information about the efforts required to implement the portal. So, if you are managing a portal development project, you should definitely have this information ready before starting the project. Security Security is one of the most important aspects of any portal. When we think about security of any portal, we must consider access to the content and the applications on the portal. You must have come across many of the portals so far. Some of the portals allow you to create your account freely; some of the portals require an authorization before creating the account while some other portals don't allow creating an account at all. Also, there are some portals which display the same information to all the users while other portals display certain information to members only. To put this in a nutshell, each of the portal has its own security policy and it operates based on that policy only. Once we have discussed/thought about users, content, and application in portal design, we should consider the security aspect of the portal. Now, let's think of some of the questions which we should normally ask to ourselves/client while considering security aspect of the portal. Can everyone freely create an account with the portal? Do we need to migrate the users from an existing user base like LDAP? Can everyone access the same information or we need to display certain information to portal members only? Can all the members of the portal access all the applications with the same privileges or certain users have more privileges over other members? And so on… When we get answers to the preceding questions, we get following information about the portal security: If everyone can create an account with the portal, then in that case we need to provide the create account functionality to the users. Also, we don't need to do any authorization on account creation. If the answer to the first question is NO, then we need to either provide some kind of authorization on account creation or we need to remove the account creation facility completely If we have to migrate the users from an existing user base, then we have to think about the migration and integration. Liferay provides integration with LDAP. If the user base is not present, then we will end up creating all the accounts manually or provide users an ability to create their accounts If all the users (including non-logged in users) can access the same information then we will keep all the information on public pages but if we want certain information to be accessed by members only, then we might consider putting that information on the pages which can be accessed only after logging in If all the members of the portal can access the same information with same privileges then we will not need any special role in the portal. However, if a certain group or a set of users have more privileges over the other—like only content creators can create content—then we will have to create a role and provide the required permission to the role When we think of the security of the portal, we are thinking about users and their access, applications and access to those applications, and other security-related aspects of the portal. It is very important to think about the security before implementing the portal to prevent unauthorized and unauthenticated access to the portal and applications within the portal.
Read more
  • 0
  • 0
  • 2837

article-image-interface-designing-games-ios
Packt
09 Dec 2011
9 min read
Save for later

Interface Designing for Games in iOS

Packt
09 Dec 2011
9 min read
  (For more resources on iPhone, see here.) Users have few expectations as to what a typical mobile application should feel like, there is often an expectation with regards to what a game should play like. Mobile gaming platforms have been popular since the Game Boy's rise to popularity in the early 90s, and users have an idea as to what games work well when on the go, and iOS games are expected to match or exceed these preconceived notions of what is possible. However, it isn't necessarily easy to produce a game on iOS, as the device presents one of the first touch screen mobile gaming experiences. There isn't much precedent as to what game genres and control styles work well. This can be beneficial for innovation, but can also lead to a great deal of heartache for any designer.   Planning your game around touch Unlike traditional mobile gaming platforms, we won't have physical buttons and a set interface blueprint to serve as a guide for our game. Mobile platforms such as the Game Boy or PlayStation Portable have a physical control pad and buttons that lend the user to an inherent understanding of the game on screen. The user can quickly pick up and play a game, because they know that there is a finite set of buttons that can control game mechanics. We're in a bit of a more difficult-to-manage scenario with iOS, as there is no control pad or face button to commonly dictate interaction on screen when in a game. Since we're on a touch screen device, we can create any interaction mechanic that we'd like, no matter how unorthodox the interface may be. This offers up an extraordinary opportunity for new gameplay experiences; however it does make our design work a bit more difficult to construct. In this recipe, we'll discuss how touch screens drastically alter the design and playability of our game. Designing a game around touch is never an easy task. Controls are difficult to implement, screen size is often limited, and we'll need to innovate on top of standard game play mechanics to provide a fun experience. While the operating system is only a few years old, there has been a significant evolution in gaming on the platform. Early games, such as Super Monkey Ball by Sega, were often ports of previous console games by big name publishers. Apple's affordable developer program allowed independent developers to step in and experiment on the platform, pushing forward intuitive new experiences like Doodle Jump, Mr. AahH!!, and Zen Bound. In recent years, the market has matured so that both traditional franchises and independent creative ventures can succeed. Getting ready To work on this recipe, it would be useful to have an iOS device along with a traditional gaming console in order to contrast the difference in mechanics between the two machines. How to do it... Depending on the type of game we plan on developing, there are a variety of strategies for success on the iPhone or iPad. However there are a few key attributes that will make any iOS game enjoyable: Remember that users will be using the iPhone or iPad as both a screen and a controller. Don't punish users for accidental interactions with the screen. Keep in mind that these are mobile devices. While a good portion of our interface will vary greatly depending upon the type of game we're looking to create, these three rules are universal and will benefit any iPhone or iPad game. With these guidelines in mind, we can move on and begin to draft up our controls and heads up display. How it works... The low level of entry and unique touch controls have helped iOS evolve into a platform where designers can reach outside of their comfort zone in an effort to release an innovative game on the platform. In step one, it's important to understand that traditionally, users and designers are trained toward expecting games to have an external controller that is used for manipulation of the game world. The screen is a separate device; either a television or portable LCD screen serves as a way to project the game. However on iOS, the screen and controller are one. Regardless as to whether users interact with our game through buttons on screen or by using a device hardware feature such as the accelerometer, it is a guarantee that the iPhone or iPad will be held in a hand while our game is being played. We should always keep this in mind when designing both our game and interface, as the user will need to comfortably hold the device while playing. If we use traditional controls through a software joystick or buttons, we should place these elements on screen in a manner that allows for the iPhone or iPad to be held comfortably while playing. Depending upon our game and orientation, we may find that specific parts of the play area are perfect for the placement of such controls while in other scenarios, we may want to give the user the ability to customize the placement of buttons to their preference. If we expect the user to tilt or shake the controller to interact with our game, we should take this into consideration as well. While it may sound somewhat clichéd, the game and its controls are one and the same. There is no separation and any design that assumes that we can quickly implement controls without taking this fact into consideration is destined to fail. Not being given a set control pad or buttons gives us the flexibility to be creative, but poor design can quickly confuse or frustrate users. In the next screenshot, we can see that Flight Control developer Firemint has used small exclamation point markers to offer up a hint as to where inbound aircraft will soon appear. This offers a quick heads up to the user who may have had their hands in a poor position. Flight Control - © 2009 Firemint Pty Inc. We expand upon this new type of game control with these new devices in step two in the previous section. Because the game controller and device screen are so intertwined, it's very likely that the user will come into accidental contact with the screen at some point. It's just too difficult to eliminate unintended taps, as the finger is an imprecise pointing device. We can assume that the user will make unintentional contact with the screen, and so we should do our best to design a play mechanic and interface that will not punish users for their mistake. For example, if we're building a racing game, it would be silly to place the pause button near the button used for acceleration, as misplaced fingers could often pause the game and frustrate users. How we go about verifying this in our application can vary based on the type of game we're looking to design, but we should be mindful to keep this philosophy salient in our work. The limited ability to include a help menu in our application will encourage users to pick up app controls through point and tap experimentation. If the user experiences frustration in their first few minutes of using the app, they'll be likely to give up on using our app. Finally in step three, we should focus on creating an interface that is mobile. While we're designing with a device that is nearly as powerful as home gaming consoles, we must keep in mind that our users will be using their iPhone or iPad when on the run. They may be playing our game on a train, or in the car, or when walking between classes, so it's important to remember that this is a slightly different game platform than what we've ever developed for before. Because users will be playing our app when on the go and users will be less likely to sit down and play our game for extended periods of time, we should prepare our gameplay and interface around this probability. Big buttons and forgiving controls are the best way to go about designing for a mobile interface. Larger targets on screen will make it easier for the user to perform an intended action, even when walking or riding around. If we'd like to take mobile usability a bit further, we could also implement modifiable controls into our app as well. Giving the user the ability to calibrate settings will enable our game to play well, regardless as to the situation they're currently in. In the next screenshot, we can see how Doodle Jump allows users to adjust the game's controls: Doodle Jump - © 2011 Lima Sky, LLC It's also important to note that we should design our interface for the rapid entry and exit that is common of iPhone users. People will be playing our game on buses, while waiting in line at a store, and in other scenarios where their time spent inside of the app may be no longer than one to two minutes. This will affect game play drastically, so it's important to test such game scenarios while we build our app. Because our first iOS game may be our first touch screen based game, or our first game in general, we should be cautious and conservative with our interface and game play mechanics. That's not to say that the creation of any game is easy; however these are significant pitfalls that could plague our work if we're not careful. There's more... While rare, there is the possibility that our iPhone can be used as a controller for a device other than itself. Using the iPhone as a controller…for the iPad Thanks to the Bluetooth integration that Apple has included in new iPhone, iPod touch, and iPad devices, it is possible to use our iPhone as a controller for iPad games, so long as the developer has produced games for both platforms and supports the feature. It isn't necessarily easy to design and develop a game that includes such a feature, but it is by no means impossible. If we're working on an expansive game, it is definitely possible to create an immersive experience where the iPhone is used to control action on the iPad.  
Read more
  • 0
  • 0
  • 2829

article-image-iphone-user-interface-starting-stopping-and-multitasking-applications
Packt
09 Dec 2011
16 min read
Save for later

iPhone User Interface: Starting, Stopping, and Multitasking Applications

Packt
09 Dec 2011
16 min read
  (For more resources on iPhone, see here.)   Starting the application with a proper Default.png When an application loads for the first time, the user is presented with a variable duration of loading time. This period can change depending on the device processor or RAM, memory requirements of the application, current free memory available on the device, and any number of other variables. Ideally, the user will only be required to sit through this period for a brief moment. However, this duration can last up to several seconds in length if we're loading an image intensive app on an older device. Apple has designed a loading screen method that is required by each app, through the inclusion of a PNG file in our app bundle. In this recipe, we'll discuss two interface strategies for this loading period. Getting ready For this recipe, we should have a computer with Photoshop or another image creation tool. We should also have knowledge of the devices and orientation types that our application will support. How to do it... Loading times are an inherent problem with all types of software, regardless of platform. As hardware has increased in speed, these times have diminished, but they haven't become non-existent. Apple created a simple design fix for this problem, offering up a quick and easy way to load an image during the loading period. Here are quick, simple steps in order to create an image that will display during the loading period: We should start by designing up an art image measuring either 320 x 480 pixels or 320 x 460 pixels (or the equivalent Retina display double resolution size), containing the art piece which we would like the user to see during the loading screen. Next, we should then save and name that file Default.png. Finally, we should include that image in the resource bundle of our application project in XCode. If we're creating a web application, we can also include the image in our HTML code so that the image is displayed when the user launches the web app. To do this, we should name our file startup.png and place the following code in our HTML header: <link rel="apple-touch-startup-image" href="/startup.png"> iOS is designed to search the bundle for a PNG with this name, and then display it on load if it's available. Once we finish these steps, we have accomplished everything we need to do to have the image load on startup. When it comes to design styles and technique on what we should include on the image, there are two different strategies that we can take: The right way Apple's documentation on the Default.png is fairly clear. According to their design documents, this image should serve as a clean visual of what the application would look like with no pre-populated data. In essence, this provides the perception that the application has already loaded, but the user is just waiting for the data to populate. It's a subtle way to trick the user into thinking our app loads quicker than it actually does. This trick works because it typically takes the brain about 2-4 seconds to see an image on screen, process the layout of what is before them, and then make a decision. Because the loading process for an application is relatively short, typically under three seconds, presenting an overlay of the interface as the Default.png loading image allows the brain to use this time to process what is about to be presented on screen. Phone - © 2007-2011 Apple Inc. As shown above, Phone, Messages, and Photos all load preview images with their Default.png displays, which offer the perception that the application loads very quickly. By preparing the user for the app during the Default.png load image period, the user will subconsciously perceive that our application loads faster than it actually does. The wrong, but possibly preferable way While we're supposed to use the loading image to prepare the user for our app, we may want this time to serve another purpose, such as a way to advertise our development team or Twitter account. It's an important and powerful moment for application branding, so we should feel free to use this moment as a way to build brand equity through use of a logo and appropriate styling. There is no set rule that says we can't use the Default.png as an advertisement of sorts, and many applications succeed using this strategy. We'll need to include a Default.png in the application package, to give our app something to display before loading has concluded. Depending on our application type and loading period, we should be able to include a screen that fits into one of these two methods with ease. How it works... Apple has designed iOS so that it is easy to present a loading screen to the user—we only need to create a PNG image, name it Default, and include it inside of our application bundle. The operating system will do the rest for us. Because this predetermined method works so well, we can instead focus on optimizing the image to best fit into our application. It's important to remember that the Default image is the first thing that the user will ever see in our app, and we should take considerable care in the creation of the art. Attention to detail with such seemingly minute application attributes is what sets outstanding applications apart. For some situations, creating an image that looks like similar to the first screen after launch will be ideal; as it will offer the perception that our application loads quicker than it actually does. This will increase user appreciation and enjoyment of our app. In other situations, it may be desirable to go with this splash screen approach instead of the prescribed approach of faking application load. For applications where loading takes a considerable period of time, usually anything over four seconds, it is difficult to use the load to ease users into our app like Apple does with Mail, Messages, or Phone. The pause becomes so long that the user instead believes that the application has broken. So in such situations, these banner loading Default.png images may provide a better alternative, offering up a way for the user to know that they have indeed loaded the correct application, but that it will still be several seconds before they're able to interact with the initial view. Regardless of what method we choose, it will be necessary to include a Default.png in with the project. With a bit of work and consideration, we can create something that will win the hearts of our user base. There's more... Now that we've learned more about different styles of Default images, we can put a bit of extra effort into going the extra mile with the image as well. Here are a few tips on how to produce a great Default.png. We can retina optimize our Default.png too Like any other art piece, we can include a Retina display specific graphic inside our application. By adding the standard @2x modifier to the end of the image, iOS will know to pull this image instead when running a higher resolution device. As the Default.png is the first image presented to the user, we should take extra effort to show that we're dedicated to a full retina optimized experience. Prepare for multiple orientations On the iPhone, we're limited to only one Default.png orientation requirement, as applications tend to be optimized for one orientation and we can create the Default image to account for the prominent orientation. However, on the iPad, each application should be designed for optimal use in either orientation. This requires us to create two Default images, one for the app launching in portrait and another for if the app launches in landscape. Apple has created an easy system for the simple creation of such different images. We only need to create the images and add a simple –Portrait or –Landscape modifier (for example, Default-Portrait.png) in order to launch the appropriate view.   Planning our application UI for a first impression In the real world, we spend a good deal of time preparing for first impressions. We tuck our shirts in, spend time making sure our hair looks perfect, and iron our shirts so that they're wrinkle free. We do this because it's a common understanding that others will greatly have their feelings toward us determined on the basis of how we look or talk during our first meeting. If we don't impress them off the bat, they'll never be willing to warm up to us. Mobile application development falls under the same sense of unspoken understanding. If our application isn't easy to manage or understand in the first 30 seconds, users will have no qualms over closing our work and deleting it off their device. Are the colors attractive? Is information easy to access? Do they seem to know what the correct next step is? These are all important questions that the user will subconsciously answer during their first several minutes inside our work. In this recipe, we'll discuss a couple of design decisions that we can make, in order to impress our users early. Getting ready Little is needed for this recipe. Ideally, the implementation of this recipe will take place throughout the course of development, as we fine tune along the way. How to do it... The Default.png image is the first visual that every user will see when they check out our app, but it isn't necessarily the first visual that their brain will take a good deal of time processing. That honor will fall on our actual application, once loaded in full glory for all eyes to behold. It's a somewhat magical moment, as our work is first presented to the audience. Like the opening line of a play, first chapter of a book, the front door to a house, the first few minutes of a game, this is an important moment in the user's determination of what they think about our app. So how do we present our application with its best foot forward? Here are a couple of simple tips, to help users quickly feel at home inside of our application: Use simple, clean In-App icons to help signify key features: When selecting icons to fall inside of Tab Bar cells or Navigation buttons, it's important to ensure that our icon use falls in line with expectations found in other applications. The magnifying glass represents search, a star presumes favorites or top performers, three dots represent that the tab contains multiple options, and a square with a pencil infers that the button composes a new email. Start by giving users a push in the right direction: Feel free to offer up a friendly push to the user from the get go. If we make the first step clear, the subsequent steps may become a bit more obvious, as shown in the following screenshot from Grades by Tapity: Grades - © Tapity Hold back sound, flashy animation, or bright colors until the user has had the chance to settle in. Offer content early, if only a little taste of what is to come. How it works... Creating an intuitive application interface from the first second a user opens our app is an art, which requires that we shape our app carefully overtime. As we add new features, create new art, or conceive new ways to present data on screen, we should always be thinking about what a new user will think upon first presentation of our app. For Step 1, Apple routinely updates the Mobile Human Interface Guidelines , https://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/MobileHIG/Introduction/Introduction.html, with suggestions on how to use icons that come built into the iOS SDK . These guidelines account for a limited quantity of icons and uses, which makes it a bit difficult to gain a good grasp of how we should truly utilize such pieces in our app. While it would be impossible to create an exhaustive list of general shapes and their associated meaning on iOS, the best we can do is make ourselves familiar with as many apps as we possibly can in order to best understand how others have paved the road of user expectations. In Step 2, we took a look at Grades by Jeremy Olsen. The application allows users to manage test scores and class grades, with an exceptional level of open-ended opportunity. No matter how complex or simple a class's grade scale may be, the application handles the data with ease. The application makes such scalability easy for the user by using a simple contextual clue on initial launch. By offering direction on how to start tracking information for a class, the user is essentially given a tutorial without even realizing that they're being taught. There is no confusion as to what the first step is, and the user can jump right in and start keeping track of their grades. For Step three, if we are in the mood, or feel as if it's necessary to make our application stand out through a good deal of noise, eccentric color, or excessive animation, that's perfectly fine. Each application has a different art strategy and depending on our target audience, these elements may very much make sense in our work. However, we should be hesitant to use such vivid visuals or loud sounds during the user's introduction to our app. While the user may be in our target audience and enjoy our app otherwise, such sudden extreme sense stimulation may be off-putting. Instead, we should slowly walk our users into the application and give them a chance to prepare for any noise or bright lights that we may throw their way. This way, the user is expecting whatever we decide to present. For example, if we offer loud noises right after the initial launch and our user is sitting in a quiet auditorium, the successive embarrassing situation may turn the user away from our application, just because we presented them with an unexpected bout of displeasure. By working the user into our loud, colorful, flashy application, we'll be less likely to scare away potential long-term users in the first five minute of using our app. With regards to Step 3, if our application is a content heavy application, such as a social network or application that features extensive listings of local sport scores, we may be inclined to encourage users to sign up for our service before we offer the meat and potatoes of our app. Most designers are confident that their content is so valuable, users will jump through whatever hoops necessary in order to gain access. However, the typical user is an impatient soul, unlikely to fill out forms in order to gain access to an app's walled garden. Instead they'll download our app, see the frictional barrier in front of the content, and decide that they're not that interested. By offering a quick glimpse, we hold some hope in convincing the user that our content is worth going through the sign up process. Service applications such as Instagram and Twitter do a great job at this, offering a handful of images or text entries before asking the user to sign up. These quick entries give an example of the wealth of content laying behind the apparent barrier of a sign up form. Through these quick previews, the user can gain an idea as to whether they'll enjoy the service or not. By using a preview method such as this, users are able to gauge interest before the sign up, saving everyone's valuable time. Finally, we know that every iOS device user is familiar with Apple's bundled applications, as they are the only applications that come pre-installed and as such, are the only applications that every user is likely to have used. We should look here for inspiration, as Apple offers a good deal of guidance with their work. When placing an icon on our Tab Bar, ask yourself if every user will instantly know the tabs function based on the imagery. If we have doubts, there is probably a better alternative icon. In many respects, this recipe isn't so much a one-time action like many others found throughout this book. Instead, it's a design philosophy which we will fine tune as we create more applications for the iPhone or iPad. There's more... Tutorials and help menus were a somewhat taboo topic during the early days of the App Store, with Apple holding a hard stance that apps requiring such a menu were too complex for the mobile platform. Times are changing a bit, with Apple themselves offering help menus in complex apps like Garageband or iMovie. Here's a tip on how to best offer support inside of our app. Lend a helping hand While most early apps were capable of success without a help menu, many new apps have become much more complex and require such a way to teach the user about app features. If we want to provide help for our users, we have two choices. One thing we could do is create a specific help view; we could do something like provide a table of topics that the user can tap upon in order to learn more about. This allows us to dive in-depth into a variety of topics, with as much detail as we feel is required. We could also provide a tutorial through on screen overlays, where tapping a help button presents short tips on screen with insight into different app features. This method works well because we can directly point at an interface element and tell the user what its purpose is. However, because we're overlaying such information on top of the interface, we must be brief when using this choice. Our app may be simple and self-explanatory enough, that we won't need one of these two methods in order to provide a help menu. However, if we think that we need to lend a hand, either of these two routes would work well.  
Read more
  • 0
  • 0
  • 2116
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 €18.99/month. Cancel anytime
article-image-iphone-customizing-our-icon-navigation-bar-and-tab-bar
Packt
09 Dec 2011
7 min read
Save for later

iPhone: Customizing our Icon, Navigation Bar, and Tab Bar

Packt
09 Dec 2011
7 min read
  (For more resources on iPhone, see here.) The application icon and essential interaction elements such as the Navigation Bar and Tab Bar are crucial for the success of our work. The user will be tapping the icon every time they go to use our app, and interact with our navigation elements throughout their entire experience in our application. If we want success, we must focus on making these components attractive and functional. Attention to detail and the presentation of these pieces will be key, and we'll need to produce our best work if we want to stand out in a sea of apps. Designing an application icon and preparing it for the user home screen It's often said that a book shouldn't be judged by its cover, but the harsh reality of mobile development is that an app is often judged by its icon. This rounded rectangle will appear on the home screen of every user, and it's important that we create something that is attractive and also a good indication as to what the user should expect after downloading our application. In this recipe, we'll create a strategy for successful app icon design. Getting ready Adobe Photoshop will be our primary tool in the design of our app icon. It may also be helpful to grab some paper and a pencil so that we can sketch out any concepts we may have before we begin working on our computer. How to do it... The application icon is a primary component of any work. Appearing in the App Store, on a user's home screen, in Spotlight searches, and more, it's an important part of our job. Let's take a look at several steps that will be useful in the creation of our app icon: We should start by with either a rough sketch or Photoshop mockup of our intended design. We should create this mock up at several sizes to help represent the different resolutions at which our icon will be viewed. After we've developed an idea that we believe is going to scale well, its time to sit down in Photoshop or Illustrator and begin work on our icon. At this point, we need to determine what size canvas we want to design our icon on. Apple requires that our icon be available at a variety of sizes, with a 512 by 512 pixel square currently being the largest required format, but we should be prepared in case this requirement changes in the future and design our icon accordingly. There are two different ways we can go about making our icon "future proof". We can go about designing the icon in a vector format using an application like Adobe Illustrator. Vector drawings will always be the best way to ensure that our icon will scale to any size, but they can be a bit more difficult to create. If we're more comfortable using a raster image manipulation program like Photoshop, it's best to create our icon at a resolution well above what we'll ever need for the App Store, starting with a canvas of 4096 by 4096 pixels square or greater. Such a large raster size will give us a piece of art that will print comfortably on sizes as large as 13 inches when printed at 300 DPI, while also easily scaling down to whatever size we need for the App Store. Once we've decided which format we're most comfortable with, its time to go about creating our icon. Once we've completed our icon, it is time to prepare it for inclusion into our application. This icon should then be named apple-touch-icon.png and placed inside of our application bundle. iOS will then automatically add the glare effect to the top half of the icon, as seen throughout the interface. The Info.plist is a file that allows us to customize a bunch of different application attributes. We'll learn how to use it to remove the icon gloss effect in an upcoming recipe titled Removing the app icon's gloss effect. After finishing our icon, we may also want to run a small focus group, much like we would in order to gain feedback on our user interface design.We can quickly set up a simple website with a form asking for opinions on our design or even email an image of the icon to friends and family in order to facilitate feedback. When looking to gather opinion on our icon, we want to better understand a user's first impression of our icon. For a good portion of purchase decisions, the icon may be the only bit of insight into our app that the user has before tapping the buy button. We want to make sure that on first impression, the typical user associates our icon with quality, simplicity, and value. If our icon looks amateur, users probably won't consider our application for purchase. How it works... Icon design is tough, primarily because we're required to design a small square that represents our application's purpose, quality, and value. It's truly a challenge to design something that works well at 512 pixels and 27 pixels. Let's take a look at how the steps above work together to create a good icon. Resolution flexibility is arguably the difficult part of icon design, as our work needs to look great at 512 pixels by 512 pixels and at 27 by 27 pixels. Small details that look great at a high resolution can really make an icon indecipherable when scaled down to the lowest resolution required: In the above screenshot, we can quickly see how an icon becomes less legible as it decreases in size. It's necessary to provide the icon to Apple in several different sizes, which can vary depending upon the iOS device we're developing our application for and the current operating system requirements from Apple. These file sizes have varied significantly throughout the life of iOS, so we should verify the current requirements in the iOS Development Center before their creation. Sebastiaan De With keeps an excellent Photoshop file for iOS icon design, complete with resolution requirements, which he updates every time Apple changes the icon requirements. We can find the file here at http://blog.cocoia.com/2010/iphone-4-icon-psd-file/ and it should reference it while designing a new icon. When building our icon, we should really take time to think about what our icon should look like and what users will think when they first set eyes on it in the App Store. This set process works because it systematically creates a piece of work that will be optimized for the various needs of iOS. There's more... It may take a bit of practice to get a firm grasp on what makes a great or poor icon. Here are a few helpful ideas, just in case we're struggling to develop an icon that we're happy with. Dropping the text We should always refrain from including a great deal of text in our app icon. Text tends to become illegible when scaled down to small resolutions such as 27 x 27, so it is often best to keep text out of our icon. If we absolutely must include text in our icon, we should use short words that are large in size and in a bold typeface. Great gradients From an art design perspective, we'll probably be including an artistic gradient in our icon to offer the illusion of brushed metal or progressive lighting. But choosing a strong color palate for a gradient can be difficult. Dezigner Folio has created a large library of fresh, modern gradients that they've offered up for free use in any project. For the entire library, feel free to visit their website at http://www.dezinerfolio.com/2007/05/03/ultimate-web-20-gradients-v30-release. If all else fails.... If we're having a rough time with icon design and all else fails, we can always hire a freelance artist or design firm to help out with the production of our application icon. A quick search of Google can help us find a multitude of artists who have become specialists in the field of icon design. Finding a talented designer can actually be quite affordable, with many freelance artists charging a hundred dollars or less for a high quality icon. As icons can be produced in Photoshop, local graphic designers or students can help out at affordable rates as well.  
Read more
  • 0
  • 0
  • 2514

article-image-unity-ios-essentials-flyby-background
Packt
08 Dec 2011
12 min read
Save for later

Unity iOS Essentials: Flyby Background

Packt
08 Dec 2011
12 min read
(For more resources on UnityiOS, see here.) Set up a background scene Typically, the background scene for the menu system will also be a scene from the game. But because the player will not be interacting with the menu's background scene, they will not be able to see it from all angles, jump on objects, and so on. It is possible to strip out many of the components from the scene to optimize it for use as a menu background. Another option is to create a brand new background scene that incorporates game assets from multiple game levels into a single menu background to give the player a full picture of the scope of our game. Again, we can achieve this by being selective about the game assets that we use and stripping out all but the most essential visual components of those assets. The background scene can be a teaser, it can include Easter Egg hints, it can contain character cameos from other games, and it can contain parts of other games. Finally, the background scene can be a selling opportunity. It can contain advertising or it can contain objects that the player may be interested in purchasing, using game purchase. The contents of the menu background scene are limited only by what we can imagine. In the following image, we show the original first level of a game that we have selected to be used as the background scene for our game: The scene is adequate and we could use it as the background for our game menu, but we want to give the game player a better idea, right on the main menu, of just how large the game is. So instead, we add some buildings from a second level (we could do more; we could make our menu level huge, but this should do for now), and come up with the new, much larger scene, as shown in the following screenshot to use as the background for our main menu: Set up the camera path Once we have decided on the final scene that we want to use as the background for our main menu, we need to decide on the path that the camera will follow as it moves through the scene. While it is not a requirement that the camera moves along a path, it adds interest to the menu, and so we will continue with that menu theme for our game. This is an opportunity for us to tease the player, since it may be some time before they arrive at a specific part of the menu scene during actual gameplay. We can flyby Easter Eggs or we can flyby specific objectives. Again, this is the part of the game where we get to be creative and draw the player into the game. If we want to, we can even defy the physics of the game and fly through things, so that we don't give away the secret of how to achieve a game objective or how to obtain an Easter Egg, but we do let the player know that they are there. We need to be careful to do this in such a way as to fade through scenes rather than clip through the geometry, so that we don't disturb the immersive feel of the game in order to hide things from the player's view. To set up a path, the first thing we need to do is create a gizmo. A gizmo is an image that appears in the Unity3D editor at the position of a game object's transform, but otherwise will not be visible in the game. As a game designer, we use gizmos to arrange these game objects graphically in the editor, rather than having to find each object in the game hierarchy, and enter x, y, and z values to position the transformation. Gizmos, while not necessary, are very useful because they allow us to create a visual representation of an otherwise empty game object in the Unity3D editor. To create a gizmo, you need two things: A gizmo image A gizmo script The following is an example of a gizmo image. It can be anything you want. In this case, we have simply chosen an image of the letter W – for waypoint. The image file is named Waypoint.tif, and it has been imported into Unity3D as a standard GUITexture as follows: The following is an example of a gizmo script that draws a waypoint gizmo image at the location of the game object transform to which it is attached: // Draw the waypoint gizmo at the Game Object's// transform position. // You can use any image that you want // This gizmo will be pickable which means you// can click on it in the editor to select// the attached game object function OnDrawGizmos (){//The image must be in Assets/Gizmos – the size of the image//is how large it will be drawn in the scene view Gizmos.DrawIcon (transform.position, "Waypoint.tif");} To use a waypoint in the editor, we need to do the following: Create an empty game object Attach the waypoint.js script to the game object The following image shows our example level with a number of waypoints added to define the path that we want the camera to follow for our menu flyby. Everywhere you see the letter W in this image, denotes a waypoint along the path: Adding waypoints and drawing a gizmo at a waypoint's location in the editor is helpful, but one more thing that we can do to make the order of the waypoints clear is to draw a line between the waypoints. So, for example, we would draw a line from wp1 to wp2, from wp2 to wp3, and so on. The following script fragment, which is part of the SeekSteer script, shows how to draw the lines between the waypoints: // draws a line from waypoint to waypoint public void OnDrawGizmos() { Vector3 l_prevWaypointPosition; Vector3 l_currentWaypointPosition; // Choose a color, it can be any color you like Gizmos.color = Color.red; // Draws a line between the last waypoint // and the first waypoint l_prevWaypointPosition = waypoints[waypoints.Length-1].position; l_currentWaypointPosition = waypoints[0].position; Gizmos.DrawLine(l_prevWaypointPosition, l_currentWaypointPosition); // Choose another color, it can be any color you like // except the first color Gizmos.color = Color.green; // For each remaining waypoint, in the waypoints array // draw a line between the two points for (int i=1;i < waypoints.Length;i++) { l_currentWaypointPosition = waypoints[i].position; l_prevWaypointPosition = waypoints[i-1].position; Gizmos.DrawLine(l_prevWaypointPosition, l_currentWaypointPosition); } } The following screenshot shows the new scene with lines being drawn between the waypoints. It's easy to identify the first and last waypoint, because they are the points with the red lines between them: Once the waypoints have been set up, we need something to follow them. There are literally dozens of ways that we can use to follow a path, and many kinds of paths that we can follow. In fact, there are complete Unity3D projects devoted to path finding. In this case, we have chosen to use the SteerSeaker method of following a path. The SteerSeaker creates an array (or list) of all the waypoints, and moves from one waypoint to the next in the same amount of time. In order to keep the time between waypoints constant, the SteerSeaker speeds up or slows down based on the distance between the waypoints, which makes it easy for us to predict the total time it will take to follow our path and create sections of both slow and fast movement. The rest of the SteerSeaker script (remember we looked at the previous image that draws lines between the waypoints) is shown as follows: This script is written in C# rather than JavaScript. While many people new to Unity3D prefer to work in either JavaScript or C#, it's important that we become familiar with both scripting languages, so that we can take advantage of all the open source resources available in the Unity3D community. While we don't need to be able to program in both languages, we do need to be able to read both languages. // SeekSteer.cs// Based on the original SeekSteer by Matthew Hughes// -- 19 April 2009// -- Uploaded to Unify Community Wiki on 19 April 2009// -- URL:http://www.unifycommunity.com/wiki/index.php?title=SeekSteer//// Changes by BurningThumb Software// -- March 2010//using UnityEngine;using System.Collections;public class SeekSteer : MonoBehaviour{ // This is the array of waypoints public Transform[] waypoints; // This is the radius, in meteres of a waypoint public float waypointRadius = 1.5f; // Damping is used to limit the rate at which // the object turns towards the next waypoint. // Smaller numbers slow down turns, larger // numbers speed up turns public float damping = 0.1f; // Set loop to true if the object loops // continuously around the waypoints and // to false if the object only goes around // one time public bool loop = false; // The time between waypoints is constant // so the object will speed up or slow down to // achieve this time regardless of the distance // between the points public float transittime = 2.0f; // Set faceHeading to true to make the object // turn to face the forward direction and to // false to not turn to face the forward // direction public bool faceHeading = true; // The current heading of the object private Vector3 currentHeading; // The desired heading of the object private Vector3 targetHeading; // The array index of the waypoint that the // object is heading toward private int targetwaypoint; // A reference to the transform of the object // used to speed up the script by caching the // reference which is used many times private Transform thisTransform; // If the object has a rigid body then this // is a reference to the rigid body of the object // used to speed up the script by caching the // reference which is used several times private Rigidbody thisRigidbody; // Use this for initialization protected void Start () { // If the waypoints array is empty this script // logs a message and disables itself. You need // to add waypoints to the array in the Unity3D // editor if (waypoints.Length <= 0) { Debug.Log("No waypoints on "+name); enabled = false; } // Cache a reference to the transform to speed // up the execution of the script thisTransform = transform; // Set the current heading to be forward currentHeading = thisTransform.forward; // The first target waypoint, is the first // one in the array targetwaypoint = 0; // Cache a reference to the attached Rigidbody to // speed up execution of the script. If // no Rigidbody is attached this will be null thisRigidbody = rigidbody; } // calculates a new heading. This is done in // fixed update just in case there is a // Rigidbody attached and physics are // involved protected void FixedUpdate () { // A simple Lerp with damping to adjust // the heading towards the current target // waypoint targetHeading = waypoints[targetwaypoint].position - thisTransform.position; currentHeading = Vector3.Lerp(currentHeading, targetHeading, damping * Time.deltaTime); } // moves us along current heading protected void Update() { // If a Rigidbody is attached then // physics is in use so add velocity if (thisRigidbody) { thisRigidbody.velocity = currentHeading * transittime; } // Otherwise set the position directly else { thisTransform.position = thisTransform.position + (currentHeading * Time.deltaTime * transittime); } // If the object needs to face the heading, // make it look that way if (faceHeading) { thisTransform.LookAt(thisTransform.position + currentHeading); } // Check to see if the object is inside the // waypoint radius if (Vector3.Distance(thisTransform.position, waypoints[targetwaypoint].position) <= waypointRadius) { // Add one to the target waypoint to select // the next waypoint targetwaypoint++; // if the next waypoint is past // the end of the array if(targetwaypoint>=waypoints.Length) { // set it back to the beginning targetwaypoint = 0; // If the object is only supposed // to transit the waypoints one // time then disables the script if (!loop) { enabled = false; } } } } With this final script, we create the SteerSeeker game object and attach not only the SteerSeaker script, but also a gizmo script to display the letter S. This is done so that we can see the position of the game object in the Unity3D editor. The following image shows the SteerSeaker object settings in the Unity3D editor: The variables declared as public in the script are the ones that will appear in the Unity3D editor. The following image shows its position on the waypoint path, as we run the game in the editor: Finally, we need to have the main camera follow the SteerSeaker object as it moves along the waypoint path. The advantage of using a script, instead of a simple timeline, is that we can create more dynamic camera movement, for example, a rollercoaster effect where the camera changes angles as it moves, or a script that "gobbles" up jewels along the path as it moves. It's important to understand the concept of using a script and its benefits, rather than simply looking at what this specific example does. Often, as in this case, example code is kept simple to convey the concept or idea, and is not meant to be the final solution that we would deploy in a game. This is done by attaching the FollowTransform script from the iPhone Standard Assets to the main camera, while assigning the SeekSteerObject to the Target Transform and checking the box Face Forward on that script. This is shown as follows: The output is shown in the following image:
Read more
  • 0
  • 0
  • 2368

article-image-getting-started-apache-solr
Packt
02 Dec 2011
8 min read
Save for later

Getting Started with Apache Solr

Packt
02 Dec 2011
8 min read
  (For more resources on Apache, see here.) We're going to get started by downloading Solr, examine its directory structure, and then finally run it. This sets you up for the next section, which tours a running Solr server. Get Solr: You can download Solr from its website: http://lucene.apache.org/ solr/. The last Solr release this article was written for is version 3.4. Solr has had several relatively minor point-releases since 3.1 and it will continue. In general I recommend using the latest release since Solr and Lucene's code are extensively tested. Lucid Imagination also provides a Solr distribution called "LucidWorks for Solr". As of this writing it is Solr 3.2 with some choice patches that came after to ensure its stability and performance. It's completely open source; previous LucidWorks releases were not as they included some extras with use limitations. LucidWorks for Solr is a good choice if maximum stability is your chief concern over newer features. Get Java: The only prerequisite software needed to run Solr is Java 5 (a.k.a. java version 1.5) or later—ideally Java 6. Typing java –version at a command line will tell you exactly which version of Java you are using, if any. Use latest version of Java! The initial release of Java 7 included some serious bugs that were discovered shortly before its release that affect Lucene and Solr. The release of Java 7u1 on October 19th, 2011 resolves these issues. These same bugs occurred with Java 6 under certain JVM switches, and Java 6u29 resolves them. Therefore, I advise you to use the latest Java release. Java is available on all major platforms including Windows, Solaris, Linux, and Apple. Visit http://www.java.com to download the distribution for your platform. Java always comes with the Java Runtime Environment (JRE) and that's all Solr requires. The Java Development Kit (JDK) includes the JRE plus the Java compiler and various diagnostic utility programs. One such useful program is jconsole, and so the JDK distribution is recommended. Solr is a Java-based web application, but you don't need to be particularly familiar with Java in order to use it. Solr's installation directory structure When you unzip Solr after downloading it, you should find a relatively straightforward directory structure: client: Convenient language-specific client APIs for talking to Solr. Ignore the client directory Most client libraries are maintained by other organizations, except for the Java client SolrJ which lies in the dist/ directory. client/ only contains solr-ruby , which has fallen out of favor compared to rsolr —both of which are Ruby Solr clients. contrib: Solr contrib modules. These are extensions to Solr. The final JAR file for each of these contrib modules is actually in dist/; so the actual files here are mainly the dependent JAR files. analysis-extras: A few text analysis components that have large dependencies. There are some "ICU" Unicode classes for multilingual support, a Chinese stemmer, and a Polish stemmer. clustering: A engine for clustering search results. dataimporthandler: The DataImportHandler (DIH) —a very popular contrib module that imports data into Solr from a database and some other sources. extraction: Integration with Apache Tika– a framework for extracting text from common file formats. This module is also called SolrCell and Tika is also used by the DIH's TikaEntityProcessor. uima: Integration with Apache UIMA—a framework for extracting metadata out of text. There are modules that identify proper names in text and identify the language, for example. To learn more, see Solr's wiki: http://wiki.apache.org/solr/SolrUIMA. velocity: Simple Search UI framework based on the Velocity templating language. dist: Solr's WAR and contrib JAR files. The Solr WAR file is the main artifact that embodies Solr as a standalone file deployable to a Java web server. The WAR does not include any contrib JARs. You'll also find the core of Solr as a JAR file, which you might use if you are embedding Solr within an application, and Solr's test framework as a JAR file, which is to assist in testing Solr extensions. You'll also see SolrJ's dependent JAR files here. docs: Documentation—the HTML files and related assets for the public Solr website, to be precise. It includes a good quick tutorial, and of course Solr's API. Even if you don't plan on extending the API, some parts of it are useful as a reference to certain pluggable Solr configuration elements—see the listing for the Java package org.apache.solr.analysis in particular. example: A complete Solr server, serving as an example. It includes the Jetty servlet engine (a Java web server), Solr, some sample data and sample Solr configurations. The interesting child directories are: example/etc: Jetty's configuration. Among other things, here you can change the web port used from the pre-supplied 8983 to 80 (HTTP default). exampledocs: Sample documents to be indexed into the default Solr configuration, along with the post.jar program for sending the documents to Solr. example/solr: The default, sample Solr configuration. This should serve as a good starting point for new Solr applications. It is used in Solr's tutorial. example/webapps: Where Jetty expects to deploy Solr from. A copy of Solr's WAR file is here, which contains Solr's compiled code. Solr's home directory and Solr cores When Solr starts, the very first thing it does is determine where the Solr home directory is. There are various ways to tell Solr where it is, but by default it's the directory named simply solr relative to the current working directory where Solr is started. You will usually see a solr.xml file in the home directory, which is optional but recommended. It mainly lists Solr cores. For simpler configurations like example/solr, there is just one Solr core, which uses Solr's home directory as its core instance directory . A Solr core holds one Lucene index and the supporting Solr configuration for that index. Nearly all interactions with Solr are targeted at a specific core. If you want to index different types of data separately or shard a large index into multiple ones then Solr can host multiple Solr cores on the same Java server. A Solr core's instance directory is laid out like this: conf: Configuration files. The two I mention below are very important, but it will also contain some other .txt and .xml files which are referenced by these two. conf/schema.xml: The schema for the index including field type definitions with associated analyzer chains. conf/solrconfig.xml: The primary Solr configuration file. conf/xslt: Various XSLT files that can be used to transform Solr's XML query responses into formats such as Atom and RSS. conf/velocity: HTML templates and related web assets for rapid UI prototyping using Solritas. The soon to be discussed "browse" UI is implemented with these templates. data: Where Lucene's index data lives. It's binary data, so you won't be doing anything with it except perhaps deleting it occasionally to start anew. lib: Where extra Java JAR files can be placed that Solr will load on startup. This is a good place to put contrib JAR files, and their dependencies. Running Solr Now we're going to start up Jetty and finally see Solr running albeit without any data to query yet. We're about to run Solr directly from the unzipped installation. This is great for exploring Solr and doing local development, but it's not what you would seriously do in a production scenario. In a production scenario you would have a script or other mechanism to start and stop the servlet engine with the operating system—Solr does not include this. And to keep your system organized, you should keep the example directly as exactly what its name implies—an example. So if you want to use the provided Jetty servlet engine in production, a fine choice then copy the example directory elsewhere and name it something else. First go to the example directory, and then run Jetty's start.jar file by typing the following command: >>cd example >>java -jar start.jar The > > notation is the command prompt. These commands will work across *nix and DOS shells. You'll see about a page of output, including references to Solr. When it is finished, you should see this output at the very end of the command prompt: 2008-08-07 14:10:50.516::INFO: Started SocketConnector @ 0.0.0.0:8983 The 0.0.0.0 means it's listening to connections from any host (not just localhost, notwithstanding potential firewalls) and 8983 is the port. If Jetty reports this, then it doesn't necessarily mean that Solr was deployed successfully. You might see an error such as a stack trace in the output if something went wrong. Even if it did go wrong, you should be able to access the web server: http://localhost:8983. Jetty will give you a 404 page but it will include a list of links to deployed web applications, which will just be Solr for this setup. Solr is accessible at: http://localhost:8983/solr, and if you browse to that page, then you should either see details about an error if Solr wasn't loaded correctly, or a simple page with a link to Solr's admin page, which should be http://localhost:8983/solr/admin/. You'll be visiting that link often. To quit Jetty (and many other command line programs for that matter), press Ctrl+C on the keyboard.
Read more
  • 0
  • 0
  • 2979

article-image-article-html5-working-with-images-and-videos
Packt
02 Dec 2011
19 min read
Save for later

HTML5: Working with Images and Videos

Packt
02 Dec 2011
19 min read
(For more resources on this topic, see here.) Introduction This article focuses on yet another very exciting topic of the HTML5 canvas, images and videos. Along with providing basic functionality for positioning, sizing, and cropping images and videos, the HTML5 canvas API also allows us to access and modify the color and transparency of each pixel for both mediums. Let's get started! Drawing an image Let's jump right in by drawing a simple image. In this recipe, we'll learn how to load an image and draw it somewhere on the canvas. How to do it... Follow these steps to draw an image in the center of the canvas: Define the canvas context: window.onload = function(){    var canvas = document.getElementById("myCanvas");    var context = canvas.getContext("2d"); Create an image object, set the onload property to a function that draws the image, and then set the source of the image:     var imageObj = new Image();    imageObj.onload = function(){        var destX = canvas.width / 2 - this.width / 2;        var destY = canvas.height / 2 - this.height / 2;                context.drawImage(this, destX, destY);    };    imageObj.src = "jet_300x214.jpg";}; Embed the canvas tag inside the body of the HTML document: <canvas id="myCanvas" width="600" height="250" style="border:1px solid black;"></canvas> How it works... To draw an image, we first need to create an image object using new Image(). Notice that we've set the onload property of the image object before defining the source of the image. It's good practice to define what we want to do with the image when it loads before setting its source. Theoretically, if we were to define the source of the image before we define the onload property; the image could possibly load before the definition is complete (although, it's very unlikely). The key method in this recipe is the drawImage() method: context.drawImage(imageObj,destX,destY); Where imageObj is the image object, and destX and destY is where we want to position the image. There's more... In addition to defining an image position with destX and destY, we can also add two additional parameters, destWidth and destHeight to define the size of our image: context.drawImage(imageObj,destX,destY,destWidth,destHeight); For the most part, it's a good idea to stay away from resizing an image with the drawImage() method, simply because the quality of the scaled image will be noticeably reduced, similar to the result when we resize an image with the width and height properties of an HTML image element. If image quality is something you're concerned about (why on earth wouldn't you be?), it's usually best to work with thumbnail images alongside bigger images if you're creating an application that needs scaled images. If, on the other hand, your application dynamically shrinks and expands images, using the drawImage() method with destWidth and destHeight to scale images is a perfectly acceptable approach. Cropping an image In this recipe, we'll crop out a section of an image and then draw the result onto the canvas. How to do it... Follow these steps to crop out a section of an image and draw the result onto the canvas. Define the canvas context: window.onload = function(){    var canvas = document.getElementById("myCanvas");    var context = canvas.getContext("2d"); Create an image object, set the onload property to a function that crops the image, and then set the source of the image:     var imageObj = new Image();    imageObj.onload = function(){    // source rectangular area        var sourceX = 550;        var sourceY = 300;        var sourceWidth = 300;        var sourceHeight = 214;            // destination image size and position        var destWidth = sourceWidth;        var destHeight = sourceHeight;        var destX = canvas.width / 2 - destWidth / 2;        var destY = canvas.height / 2 - destHeight / 2;                context.drawImage(this, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);    };    imageObj.src = "jet_1000x714.jpg";}; Embed the canvas tag inside the body of the HTML document: <canvas id="myCanvas" width="600" height="250" style="border:1px solid black;"></canvas> How it works... In the last recipe, we discussed two different ways that we can use the drawImage() method to draw images on the canvas. In the first case, we can pass an image object and a position to simply draw an image at the given position. In the second case, we can pass an image object, a position, and a size to draw an image at the given position with the given size. Additionally, we can also add six more parameters to the drawImage() method if we wanted to crop an image: Context.drawImage(imageObj,sourceX,sourceY,sourceWidth, sourceHight, sourceHeight,sourceHeight, destX, destY, destWidth, destHeight); Take a look at the following diagram: As you can see, sourceX and sourceY refer to the top-left corner of the cropped region in the source image. sourceWidth and sourceHeight refer to the width and height of the cropped image from the source. destX and destY refer to the position of the cropped image on the canvas, and destWidth and destHeight refer to the width and height of the resulting cropped image. If you don't intend to scale a cropped image, then destWidth equals sourceWidth and destHeight equals sourceHeight. Copying and pasting sections of the canvas In this recipe, we'll cover yet another interesting usage of the drawImage() method—copying sections of the canvas. First, we'll draw a spade in the center of the canvas, then we'll copy the right side of the spade and then paste it to the left, and then we'll copy the left side of the spade and then paste it to the right. How to do it... Follow these steps to draw a spade in the center of the canvas and then copy-and-paste sections of the shape back onto the canvas: Define the canvas context: window.onload = function(){    // drawing canvas and context    var canvas = document.getElementById("myCanvas");    var context = canvas.getContext("2d"); Draw a spade in the center of the canvas using the drawSpade() function:     // draw spade    var spadeX = canvas.width / 2;    var spadeY = 20;    var spadeWidth = 140;    var spadeHeight = 200;        // draw spade in center of canvas    drawSpade(context, spadeX, spadeY, spadeWidth, spadeHeight); Copy the right half of the spade and then paste it on the canvas to the left of the spade using the drawImage() method:     context.drawImage(    canvas,             spadeX,         // source x    spadeY,         // source y    spadeWidth / 2,     // source width    spadeHeight,       // source height    spadeX - spadeWidth,  // dest x    spadeY,         // dest y    spadeWidth / 2,     // dest width    spadeHeight        // dest height  ); Copy the left half of the spade and then paste it on the canvas to the right of the spade using the drawImage() method:     context.drawImage(    canvas,     spadeX - spadeWidth / 2,  // source x       spadeY,           // source y    spadeWidth / 2,       // source width    spadeHeight,         // source height    spadeX + spadeWidth / 2,   // dest x    spadeY,           // dest y    spadeWidth / 2,       // dest width    spadeHeight          // dest height  );}; Embed the canvas inside the body of the HTML document: <canvas id="myCanvas" width="600" height="250" style="border:1px solid black;"></canvas> How it works... To copy a section of the canvas, we can pass the canvas object to the drawImage() method instead of an image object: Context.drawImage(canvas,sourceX,sourceY,sourceWidth, sourceHight, sourceHeight,sourceHeight, destX, destY, destWidth, destHeight); As we'll see in the next recipe, not only can we copy sections of an image or a canvas with drawImage(), we can also copy sections of HTML5 video. Working with video Although the HTML5 canvas API doesn't provide a direct method for drawing videos on the canvas like it does for images, we can certainly work with videos by capturing frames from a hidden video tag and then copying them onto the canvas with a loop. Getting ready... Before we get started, let's talk about the supported HTML5 video formats for each browser. At the time of writing, the video format war continues to rage on, in which all of the major browsers—Chrome, Firefox, Opera, Safari, and IE—continue to drop and add support for different video formats. To make things worse, each time a major browser adds or drops support for a particular video format, developers have to once again re-formulate the minimal set of video formats that's required for their applications to work across all browsers. At the time of writing, the three major video formats are Ogg Theora, H.264, and WebM. For the video recipes in this article, we'll be using a combination of Ogg Theora and H.264. When working with video, it's strongly advised that you do a search online to see what the current status is for video support as it is a subject to change at any moment. There's more! Once you've decided which video formats to support, you'll probably need a video format converter to convert the video file that you have on hand to other video formats. One great option for converting video formats is the Miro Video Converter, which supports video format conversions for just about any video format including Ogg Theora, H.264, or WebM formats. Miro Video Converter is probably the most common video converter available at the time of writing, although you can certainly use any other video format converter of your liking. You can download Miro Video Converter from: http://www.mirovideoconverter.com/. How to do it... Follow these steps to draw a video onto the canvas: Create a cross-browser method that requests an animation frame: window.requestAnimFrame = (function(callback){    return window.requestAnimationFrame ||    window.webkitRequestAnimationFrame ||    window.mozRequestAnimationFrame ||    window.oRequestAnimationFrame ||    window.msRequestAnimationFrame ||    function(callback){        window.setTimeout(callback, 1000 / 60);    };})(); Define the drawFrame() function which copies the current video frame, pastes it onto the canvas using the drawImage() method, and then requests a new animation frame to draw the next frame: function drawFrame(context, video){    context.drawImage(video, 0, 0);    requestAnimFrame(function(){        drawFrame(context, video);    });} Define the canvas context, get the video tag, and draw the first video frame: window.onload = function(){    var canvas = document.getElementById("myCanvas");    var context = canvas.getContext("2d");    var video = document.getElementById("myVideo");    drawFrame(context, video);}; Embed the canvas and the video tag inside the body of the HTML document: <video id="myVideo" autoplay="true" loop="true" style="display:none;">    <source src="BigBuckBunny_640x360.ogv" type="video/ogg"/><source src="BigBuckBunny_640x360.mp4" type="video/mp4"/></video><canvas id="myCanvas" width="600" height="360" style="border:1px solid black;"></canvas> How it works... To draw a video on an HTML5 canvas, we first need to embed a hidden video tag in the HTML document. In this recipe, and in future video recipes, I've used the Ogg Theora and H.264 (mp4) video formats. Next, when the page loads, we can use our cross-browser requestAnimFrame() method to capture the video frames as fast as the browser will allow and then draw them onto the canvas. Getting image data Now that we know how to draw images and videos, let's try accessing the image data to see what kind of properties we can play with. WARNING: This recipe must run on a web server due to security constraints with the getImageData() method. Getting ready... Before we get started working with image data, it's important that we cover canvas security and the RGBA color space. So why is canvas security important with respect to accessing image data? Simply put, in order to access image data, we need to use the getImateData() method of the canvas context which will throw a SECURITY_ERR exception if we try accessing image data from an image residing on a non-web server file system, or if we try accessing image data from an image on a different domain. In other words, if you're going to try out these demos for yourself, they won't work if your files reside on your local file system. You'll need to run the rest of the recipes in this article on a web server.Next, since pixel manipulation is all about altering the RGB values of pixels, we should probably cover the RGB color model and the RGBA color space while we're at it. RGB represents the red, green, and blue components of a pixel's color. Each component is an integer between 0 and 255, where 0 represents no color and 255 represents full color. RGB values are often times represented as follows: rgb(red,green,blue) Here are some common color values represented with the RGB color model: rgb(0,0,0) = blackrgb(255,255,255) = whitergb(255,0,0) = redrgb(0,255,0) = greenrgb(0,0,255) = bluergb(255,255,0) = yellowrgb(255,0,255) = magentargb(0,255,255) = cyan In addition to RGB, pixels can also have an alpha channel which refers to its opacity. An alpha channel of 0 is a fully transparent pixel, and an alpha channel of 255 is a fully opaque pixel. RGBA color space simply refers to the RGB color model (RGB) plus the alpha channel (A). Be careful not to confuse the alpha channel range of HTML5 canvas pixels, which are integers 0 to 255, and the alpha channel range of CSS colors, which are decimals 0.0 to 1.0. How to do it... Follow these steps to write out the image data properties of an image: Define a canvas context: window.onload = function(){    var canvas = document.getElementById("myCanvas");    var context = canvas.getContext("2d"); Create an image object, set the onload property to a function which draws the image:     var imageObj = new Image();    imageObj.onload = function(){        var sourceWidth = this.width;        var sourceHeight = this.height;        var destX = canvas.width / 2 - sourceWidth / 2;        var destY = canvas.height / 2 - sourceHeight / 2;        var sourceX = destX;        var sourceY = destY;            // draw image on canvas        context.drawImage(this, destX, destY); Get the image data, write out its properties, and then set the source of the image object outside of the onload definition:     // get image data from the rectangular area     // iof the canvas containing the image        var imageData = context.getImageData(sourceX, sourceY, sourceWidth, sourceHeight);        var data = imageData.data;        // write out the image data properties        var str = "width=" + imageData.width + ", height=" + imageData.height + ", data length=" + data.length;        context.font = "12pt Calibri";        context.fillText(str, 4, 14);    };    imageObj.src = "jet_300x214.jpg";}; Embed the canvas tag into the body of the HTML document: <canvas id="myCanvas" width="600" height="250" style="border:1px solid black;"></canvas> How it works... The idea behind this recipe is to draw an image, get its image data, and then write out the image data properties to the screen. As you can see from the preceding code, we can get the image data using the getImageData() method of the canvas context: context.getImageData(sourceX,sourceY,sourceWidth,sourceHeight); Notice that the getImageData() method only works with the canvas context and not the image object itself. As a result, in order to get image data, we must first draw an image onto the canvas and then use getImageData() method of the canvas context. The ImageData object contains three properties: width, height, and data. As you can see from the screenshot in the beginning of this recipe, our ImageData object contains a width property of 300, a height property of 214, and a data property which is an array of pixel information, which in this case has a length of 256,800 elements. The key to the ImageData object, in all honesty, is the data property. The data property contains the RGBA information for each pixel in our image. Since our image is made up of 300 * 214 = 64,200 pixels, the length of this array is 4 * 64,200 = 256,800 elements. Introduction to pixel manipulation: inverting image colors Now that we know how to access image data, including the RGBA for every pixel in an image or video, our next step is to explore the possibilities of pixel manipulation. In this recipe, we'll invert the colors of an image by inverting the color of each pixel. WARNING: This recipe must be run on a web server due to security constraints with the getImageData() method. How to do it... Follow these steps to invert the colors of an image: Define the canvas context: window.onload = function(){    var canvas = document.getElementById("myCanvas");    var context = canvas.getContext("2d"); Create an image object and set the onload property to a function that draws the image and gets the image data:     var imageObj = new Image();    imageObj.onload = function(){        var sourceWidth = this.width;        var sourceHeight = this.height;        var sourceX = canvas.width / 2 - sourceWidth / 2;        var sourceY = canvas.height / 2 - sourceHeight / 2;        var destX = sourceX;        var destY = sourceY;                context.drawImage(this, destX, destY);                var imageData = context.getImageData(sourceX, sourceY, sourceWidth, sourceHeight);        var data = imageData.data; Loop through all of the pixels in the image and invert the colors:         for (var i = 0; i < data.length; i += 4) {            data[i] = 255 - data[i]; // red            data[i + 1] = 255 - data[i + 1]; // green            data[i + 2] = 255 - data[i + 2]; // blue            // i+3 is alpha (the fourth element)        } Overwrite the original image with the manipulated image, and then set the source of the image outside of the onload definition:         // overwrite original image with        // new image data        context.putImageData(imageData, destX, destY);    };    imageObj.src = "jet_300x214.jpg";}; Embed the canvas tag into the body of the HTML document: <canvas id="myCanvas" width="600" height="250" style="border:1px solid black;"></canvas> How it works... To invert the color of an image using HTML5 canvas, we can simply loop through all of the pixels in an image and then invert each pixel using a color inverting algorithm. Don't worry it's easier than it sounds. To invert a pixel's color, we can invert each of its RGB components by subtracting each value from 255 as follows: data[i  ] = 255 - data[i  ]; // reddata[i+1] = 255 - data[i+1]; // greendata[i+2] = 255 - data[i+2]; // blue Once the pixels have been updated, we can redraw the image using the putImageData() method of the canvas context: context.putImageData(imageData, destX, destY);  This method basically allows us to draw an image using image data instead of a source image with the drawImage() method.
Read more
  • 0
  • 0
  • 1939
article-image-microsoft-sharepoint-creating-various-content-types
Packt
02 Dec 2011
7 min read
Save for later

Microsoft SharePoint : Creating Various Content Types

Packt
02 Dec 2011
7 min read
(For more resources on Microsoft SharePoint, see here.) SharePoint content types are used to make it simpler for site managers to standardize what content and associated metadata gets uploaded to lists and libraries on the site. In this article, we'll take a look at how you can create various content types and assign them to be used in site containers. As a subset of more complex content types, a document set will allow your users to store related items in libraries as a set of documents sharing common metadata. This approach will allow your users to run business processes on a batch of items in the document set as well as the whole set. In this article, we'll take a look at how you can define a document set to be used on your site. Since users mostly interact with your SharePoint site through pages and views, the ability to modify SharePoint pages to accommodate business user requirements becomes an important part of site management. In this article, we'll take a look at how you can create and modify pages and content related to them. We will also take a look at how you can provision simple out-of-the-box web parts to your SharePoint publishing pages and configure their properties. Creating basic and complex content types SharePoint lists and libraries can store a variety of content on the site. SharePoint also has a user interface to customize what information you can collect from users to be attached as an item metadata. In the scenario where the entire intranet or the department site within your organization requires a standard set of metadata to be collected with list and library items, content types are the easiest approach to implement the requirement. With content types, you can define the type of business content your users will be interacting with. Once defined, you can also add a metadata field and any applicable validation to them. Once defined, you can attach the newly created content type to the library or list of your choice so that newly uploaded or modified content can conform to the rules you defined on the site. Getting ready Considering you have already set up your virtual development environment, we'll get right into authoring our script. It's assumed you are familiar with how to interact with SharePoint lists and libraries using PowerShell. In this recipe, we'll be using PowerGUI to author the script, which means you will be required to be logged in with an administrator's role on the target Virtual Machine. How to do it... Let's take a look at how we can provision site content types using PowerShell as follows: Click Start | All Programs | PowerGUI | PowerGUI Script Editor. In the main script editing window of PowerGUI, add the following script: # Defining script variables$SiteUrl = "http://intranet.contoso.com"$ListName = "Shared Documents"# Loading Microsoft.SharePoint.PowerShell $snapin = Get-PSSnapin | Where-Object {$_.Name -eq 'Microsoft.SharePoint.Powershell'}if ($snapin -eq $null) {Write-Host "Loading SharePoint Powershell Snapin"Add-PSSnapin "Microsoft.SharePoint.Powershell"}$SPSite = Get-SPSite | Where-Object {$_.Url -eq $SiteUrl} if($SPSite -ne $null) { Write-Host "Connecting to the site" $SiteUrl ",list " $ListName $RootWeb = $SPSite.RootWeb $SPList = $RootWeb.Lists[$ListName] Write-Host "Creating new content type from base type" $DocumentContentType = $RootWeb.AvailableContentTypes["Document"] $ContentType = New-Object Microsoft.SharePoint.SPContentType -ArgumentList @($DocumentContentType, $RootWeb.ContentTypes, "Org Document") Write-Host "Adding content type to site" $ct = $RootWeb.ContentTypes.Add($ContentType) Write-Host "Creating new fields" $OrgDocumentContentType = $RootWeb.ContentTypes[$ContentType.Id] $OrgFields = $RootWeb.Fields $choices = New-Object System.Collections.Specialized.StringCollection $choices.Add("East") $choices.Add("West") $OrgDivision = $OrgFields.Add("Division", [Microsoft.SharePoint.SPFieldType]::Choice, $false, $false, $choices) $OrgBranch = $OrgFields.Add("Branch", [Microsoft.SharePoint.SPFieldType]::Text, $false) Write-Host "Adding fields to content type" $OrgDivisionObject = $OrgFields.GetField($OrgDivision) $OrgBranchObject = $OrgFields.GetField($OrgBranch) $OrgDocumentContentType.FieldLinks.Add($OrgDivisionObject) $OrgDocumentContentType.FieldLinks.Add($OrgBranchObject) $OrgDocumentContentType.Update() Write-Host "Associating content type to list" $ListName $association = $SPList.ContentTypes.Add($OrgDocumentContentType) $SPList.ContentTypesEnabled = $true $SPList.Update() Write-Host "Content type provisioning complete" } $SPSite.Dispose() Click File | Save to save the script to your development machine's desktop. Set the filename of the script to CreateAssociateContentType.ps1. Open the PowerShell console window and call CreateAssociateContentType. ps1 using the following command: PS C:UsersAdministratorDesktop> . CreateAssociateContentType.ps1 As a result, your PowerShell script will create a site structure as shown in the following screenshot: Now, from your browser, let's switch to our SharePoint Intranet: http://intranet.contoso.com. From the home page's Quick launch, click the Shared Documents link. On the ribbon, click the Library tab and select Settings | Library Settings. Take note of the newly associated content type added to the Content Types area of the library settings, as shown in the following screenshot: Navigate back to the Shared Documents library from the Quick launch menu on your site and select any of the existing documents in the library. From the ribbons Documents tab, click Manage | Edit Properties. Take note of how the item now has the Content Type option available, where you can pick newly provisioned Org Document content type. Pick the Org Document content type and take note of the associated metadata showing up for the new content type, as shown in the following screenshot: How it works... First, we defined the script variables. In this recipe, the variables include a URL of the site where the content types are provisioned, http://intranet.contoso.com, and a document library to which the content type is associated: $ListName = "Shared Documents" Once a PowerShell snap-in has been loaded, we get a hold of the instance of the current site and its root web. Since we want our content type to inherit from the parent rather than just being defined from the scratch, we get a hold of the existing parent content type first, using the following command: $DocumentContentType = $RootWeb.AvailableContentTypes["Document"] Next, we created an instance of a new content type inheriting from our parent content type and provisioned it to the root site using the following command: $ContentType = New-Object Microsoft.SharePoint.SPContentType -ArgumentList @($DocumentContentType, $RootWeb.ContentTypes, "Org Document") Here, the new object takes the following parameters: the content type representing a parent, a web to which the new content type will be provisioned to, and the display name for the content type. Once our content type object has been created, we add it to the list of existing content types on the site: $ct = $RootWeb.ContentTypes.Add($ContentType) Since most content types are unique by the fields they are using, we will add some business- specific fields to our content type. First, we get a hold of the collection of all of the available fields on the site: $OrgFields = $RootWeb.Fields Next, we create a string collection to hold the values for the choice field we are going to add to our content type: $choices = New-Object System.Collections.Specialized.StringCollection The field with list of choices was called Division, representing a company division. We provision the field to the site using the following command: $OrgDivision = $OrgFields.Add("Division", [Microsoft.SharePoint.SPFieldType]::Choice, $false, $false, $choices) In the preceding command, the first parameter is the name of the field, followed by the type of the field, which in our case is choice field. We then specify whether the field will be a required field, followed by a parameter indicating whether the field name will be truncated to eight characters. The last parameter specifies the list of choices for the choice field. Another field we add, representing a company branch, is simpler since it's a text field. We define the text field using the following command: $OrgBranch = $OrgFields.Add("Branch", [Microsoft.SharePoint.SPFieldType]::Text, $false) We add both fields to the content type using the following commands: $OrgDocumentContentType.FieldLinks.Add($OrgDivisionObject)$OrgDocumentContentType.FieldLinks.Add($OrgBranchObject) The last part is to associate the newly created content type to a library, in our case Shared Documents. We use the following command to associate the content type to the library: $association = $SPList.ContentTypes.Add($OrgDocumentContentType) To ensure the content types on the list are enabled, we set the ContentTypesEnabled property of the list to $true.  
Read more
  • 0
  • 0
  • 3661

article-image-jira-programming-workflows
Packt
01 Dec 2011
20 min read
Save for later

JIRA: Programming Workflows

Packt
01 Dec 2011
20 min read
(For more resources on this topic, see here.) Introduction Workflows are one standout feature which help users to transform JIRA into a user-friendly system. It helps users to define a lifecycle for the issues, depending on the issue type, the purpose for which they are using JIRA, and so on. As the Atlassian documentation says at http://confluence.atlassian.com/display/JIRA/Configuring+Workflow: A JIRA workflow is the set of steps and transitions an issue goes through during its lifecycle. Workflows typically represent business processes. JIRA uses Opensymphony's OSWorkflow which is highly configurable, and more importantly pluggable, to cater for the various requirements. JIRA uses three different plugin modules to add extra functionalities into its workflow, which we will see in detail through this chapter. To make things easier, JIRA ships with a default workflow. We can't modify the default workflow, but can copy it into a new workflow and amend it to suit our needs. Before we go into the development aspect of a workflow, it makes sense to understand the various components of a workflow. The two most important components of a JIRA workflow are Step and Transition. At any point of time, an Issue will be in a step. Each step in the workflow is linked to a workflow Status (http://confluence.atlassian.com/display/JIRA/Defining+%27Status%27+F ield+Values) and it is this status that you will see on the issue at every stage. A transition, on the other hand, is a link between two steps. It allows the user to move an issue from one step to another (which essentially moves the issue from one status to another). Few key points to remember or understand about a workflow: An issue can exist in only one step at any point in time A status can be mapped to only one step in the workflow A transition is always one-way. So if you need to go back to the previous step, you need a different transition A transition can optionally specify a screen to be presented to the user with the right fields on it OSWorkflow, and hence JIRA, provides us with the option of adding various elements into a workflow transition which can be summarized as follows: Conditions: A set of conditions that need to be satisfied before the user can actually see the workflow action (transition) on the issue Validators: A set of validators which can be used to validate the user input before moving to the destination step Post Functions: A set of actions which will be performed after the issue is successfully moved to the destination step These three elements give us the flexibility of handling the various use cases when an issue is moved from one status to another. JIRA ships with a few built-in conditions, validators, and post functions. There are plugins out there which also provide a wide variety of useful workflow elements. And if you still don't find the one you are looking for, JIRA lets us write them as plugins. We will see how to do it in the various recipes in this chapter. Hopefully, that gives you a fair idea about the various workflow elements. A lot more on JIRA workflows can be found in the JIRA documentation at http://confluence.atlassian.com/display/JIRA/Configuring+Workflow. Writing a workflow condition What are workflow conditions? They determine whether a workflow action is available or not. Considering the importance of a workflow in installations and how there is a need to restrict the actions either to a set of people, roles, and so on, or based on some criteria (for example, the field is not empty!), writing workflow conditions is inevitable. Workflow conditions are created with the help of the workflow-condition module. The following are the key attributes and elements supported. See http://confluence.atlassian.com/display/JIRADEV/Workflow+Plugin+Modules#WorkflowPluginModules-Conditions for more details. Attributes: Name Description key This should be unique within the plugin. class Class to provide contexts for rendered velocity templates. Must implement the com.atlassian.jira.plugin.workflow.WorkflowPluginConditionFactory interface. i18n-name-key The localization key for the human-readable name of the plugin module. name Human-readable name of the workflow condition. Elements: Name Description description Description of the workflow condition. condition-class Class to determine whether the user can see the workflow transition. Must implement com.opensymphony.workflow.Condition. Recommended to extend the com.atlassian.jira.workflow.condition.AbstractJiraCondition class. resource type="velocity" Velocity templates for the workflow condition views. Getting ready As usual, create a skeleton plugin. Create an eclipse project using the skeleton plugin and we are good to go! How to do it... In this recipe, let's assume we are going to develop a workflow condition that limits a transition only to the users belonging to a specific project role. The following are the steps to write our condition: Define the inputs needed to configure the workflow condition. We need to implement the WorkflowPluginFactory interface, which mainly exists to provide velocity parameters to the templates. It will be used to extract the input parameters that are used in defining the condition. To make it clear, the inputs here are not the inputs while performing the workflow action, but the inputs in defining the condition. The condition factory class, RoleConditionFactory in this case, extends the AbstractWorkflowPluginFactory, which implements the WorkflowPluginFactory interface. There are three abstract methods that we should implement, that is, getVelocityParamsForInput, getVelocityParamsForEdit, and getVelocityParamsForView. All of them, as the name suggests, are used for populating the velocity parameters for the different scenarios. In our example, we need to limit the workflow action to a certain project role, and so we need to select the project role while defining the condition. The three methods will be implemented as follows: private static final String ROLE_NAME = "role";private static final String ROLES = "roles";.......@Override  protected void getVelocityParamsForEdit(Map<String, Object>velocityParams, AbstractDescriptor descriptor) {    velocityParams.put(ROLE, getRole(descriptor));    velocityParams.put(ROLES, getProjectRoles());  }   @Override  protected void getVelocityParamsForInput(Map<String, Object> velocityParams) {    velocityParams.put(ROLES, getProjectRoles());  }   @Override  protected void getVelocityParamsForView(Map<String, Object> velocityParams, AbstractDescriptor descriptor) {    velocityParams.put(ROLE, getRole(descriptor));  } Let's look at the methods in detail: getVelocityParamsForInput: This method defines the velocity parameters for input scenario, that is, when the user initially configures the workflow. In our example, we need to display all the project roles so that the user can select one to define the condition. The method getProjectRoles merely returns all the project roles and the collection of roles is then put into the velocity parameters with the key ROLES. getVelocityParamsForView: This method defines the velocity parameters for the view scenario, that is, how the user sees the condition after it is configured. In our example, we have defined a role and so we should display it to the user after retrieving it back from the workflow descriptor. If you have noticed, the descriptor, which is an instance of AbstractDescriptor, is available as an argument in the method. All we need is to extract the role from the descriptor, which can be done as follows: private ProjectRole getRole(AbstractDescriptor descriptor){    if (!(descriptor instanceof ConditionDescriptor)) {      throw new IllegalArgumentException("Descriptor must be aConditionDescriptor.");    }      ConditionDescriptor functionDescriptor = (ConditionDescriptor)descriptor;     String role = (String) functionDescriptor.getArgs().get(ROLE);    if (role!=null && role.trim().length()>0)      return getProjectRole(role);    else       return null;  } Just check if the descriptor is a condition descriptor or not, and then extract the role as shown in the preceding snippet. getVelocityParamsForEdit: This method defines the velocity parameters for the edit scenario, that is, when the user modifies the existing condition. Here we need both the options and the selected value. Hence, we put both the project roles collection and the selected role on to the velocity parameters. The second step is to define the velocity templates for each of the three aforementioned scenarios: input, view, and edit. We can use the same template here for input and edit with a simple check to keep the old role selected for the edit scenario. Let us look at the templates: edit-roleCondition.vm: Displays all project roles and highlights the already-selected one in the edit mode. In the input mode, the same template is reused, but the selected role will be null and hence a null check is done: <tr bgcolor="#ffffff">    <td align="right" valign="top" bgcolor="#fffff0">        <span class="label">Project Role:</span>    </td>    <td bgcolor="#ffffff" nowrap>        <select name="role" id="role">        #foreach ($field in $roles)          <option value="${field.id}"            #if ($role && (${field.id}==${role.id}))                SELECTED            #end            >$field.name</option>        #end        </select>        <br><font size="1">Select the role in which the user should be present!</font>    </td></tr> view-roleCondition.vm: Displays the selected role: #if ($role)  User should have ${role.name} Role!#else  Role Not Defined#end The third step is to write the actual condition. The condition class should extend the AbstractJiraCondition class. Here we need to implement the passesCondition method. In our case, we retrieve the project from the issue, check if the user has the appropriate project role, and return true if the user does: public boolean passesCondition(Map transientVars, Map args,PropertySet ps) throws WorkflowException {    Issue issue = getIssue(transientVars);    User user = getCaller(transientVars, args);     project project = issue.getProjectObject();    String role = (String)args.get(ROLE);    Long roleId = new Long(role);     return projectRoleManager.isUserInProjectRole(user,projectRoleManager.getProjectRole(roleId), project);} The issue on which the condition is checked can be retrieved using the getIssue method implemented in the AbstractJiraCondition class. Similarly, the user can be retrieved using the getCaller method. In the preceding method, projectRoleManager is injected in the constructor, as we have seen before. We can see that the ROLE key is used to retrieve the project role ID from the args parameter in the passesCondition method. In order for the ROLE key to be available in the args map, we need to override the getDescriptorParams method in the condition factory class, RoleConditionFactory in this case. The getDescriptorParams method returns a map of sanitized parameters, which will be passed into workflow plugin instances from the values in an array form submitted by velocity, given a set of name:value parameters from the plugin configuration page (that is, the 'input-parameters' velocity template). In our case, the method is overridden as follows: public Map<String, String> getDescriptorParams(Map<String, Object>conditionParams) {    if (conditionParams != null &&conditionParams.containsKey(ROLE))        {            return EasyMap.build(ROLE,extractSingleParam(conditionParams, ROLE));        }        // Create a 'hard coded' parameter        return EasyMap.build();  } The method here builds a map of the key:value pair, where key is ROLE and the value is the role value entered in the input configuration page. The extractSingleParam method is implemented in the AbstractWorkflowPluginFactory class. The extractMultipleParams method can be used if there is more than one parameter to be extracted! All that is left now is to populate the atlassian-plugin.xml file with the aforementioned components. We use the workflow-condition module and it looks like the following block of code: <workflow-condition key="role-condition" name="Role BasedCondition"  class="com.jtricks.RoleConditionFactory">    <description>Role Based Workflow Condition</description>    <condition-class>com.jtricks.RoleCondition</condition-class>    <resource type="velocity" name="view"location="templates/com/jtricks/view-roleCondition.vm"/>    <resource type="velocity" name="input-parameters"location="templates/com/jtricks/edit-roleCondition.vm"/>    <resource type="velocity" name="edit-parameters" location="templates/com/jtricks/edit-roleCondition.vm"/></workflow-condition> Package the plugin and deploy it! How it works... After the plugin is deployed, we need to modify the workflow to include the condition. The following screenshot is how the condition looks when it is added initially. This, as you now know, is rendered using the input template: After the condition is added (that is, after selecting the Developers role), the view is rendered using the view template and looks as shown in the following screenshot: (Move the mouse over the image to enlarge.) If you try to edit it, the screen will be rendered using the edit template, as shown in the following screenshot: Note that the Developers role is already selected. After the workflow is configured, when the user goes to an issue, he/she will be presented with the transition only if he/she is a member of the project role where the issue belongs. It is while viewing the issue that the passesCondition method in the condition class is executed. Writing a workflow validator Workflow validators are specific validators that check whether some pre-defined constraints are satisfied or not while progressing on a workflow. The constraints are configured in the workflow and the user will get an error if some of them are not satisfied. A typical example would be to check if a particular field is present or not before the issue is moved to a different status. Workflow validators are created with the help of the workflow- validator module. The following are the key attributes and elements supported. Attributes: Name Description key This should be unique within the plugin. class Class to provide contexts for rendered velocity templates. Must implement the com.atlassian.jira.plugin.workflow.WorkflowPluginValidatorFactory interface. i18n-name-key The localization key for the human-readable name of the plugin module. name Human-readable name of the workflow validator. Elements: Name Description description Description of the workflow validator. validator-class Class which does the validation. Must implement com.opensymphony.workflow.Validator. resource type="velocity" Velocity templates for the workflow validator views. See http://confluence.atlassian.com/display/JIRADEV/Workflow+Plugin+Modules#WorkflowPluginModules-Validators for more details. Getting ready As usual, create a skeleton plugin. Create an eclipse project using the skeleton plugin and we are good to go! How to do it... Let us consider writing a validator that checks whether a particular field has a value entered on the issue or not! We can do this using the following steps: Define the inputs needed to configure the workflow validator: We need to implement the WorkflowPluginValidatorFactory interface, which mainly exists to provide velocity parameters to the templates. It will be used to extract the input parameters that are used in defining the validator. To make it clear, the inputs here are not the input while performing the workflow action, but the inputs in defining the validator. The validator factory class, FieldValidatorFactory in this case, extends the AbstractWorkflowPluginFactory interface and implements the WorkflowPluginValidatorFactory interface. Just like conditions, there are three abstract methods that we should implement. They are getVelocityParamsForInput, getVelocityParamsForEdit, and getVelocityParamsForView. All of them, as the names suggest, are used for populating the velocity parameters in different scenarios. In our example, we have a single input field, which is the name of a custom field. The three methods will be implemented as follows: @Overrideprotected void getVelocityParamsForEdit(Map velocityParams,AbstractDescriptor descriptor) {    velocityParams.put(FIELD_NAME, getFieldName(descriptor));  velocityParams.put(FIELDS, getCFFields());} @Overrideprotected void getVelocityParamsForInput(Map velocityParams) {    velocityParams.put(FIELDS, getCFFields());} @Overrideprotected void getVelocityParamsForView(Map velocityParams,AbstractDescriptor descriptor) {    velocityParams.put(FIELD_NAME, getFieldName(descriptor));} You may have noticed that the methods look quite similar to the ones in a workflow condition, except for the business logic! Let us look at the methods in detail: getVelocityParamsForInput: This method defines the velocity parameters for input scenario, that is, when the user initially configures the workflow. In our example, we need to display all the custom fields, so that the user can select one to use in the validator. The method getCFFields returns all the custom fields and the collection of fields is then put into the velocity parameters with the key fields. getVelocityParamsForView: This method defines the velocity parameters for the view scenario, that is, how the user sees the validator after it is configured. In our example, we have defined a field and so we should display it to the user after retrieving it back from the workflow descriptor. You may have noticed that the descriptor, which is an instance of AbstractDescriptor, is available as an argument in the method. All we need is to extract the field name from the descriptor, which can be done as follows: private String getFieldName(AbstractDescriptor descriptor){  if (!(descriptor instanceof ValidatorDescriptor)) {    throw new IllegalArgumentException('Descriptor must be aValidatorDescriptor.');  }    ValidatorDescriptor validatorDescriptor = (ValidatorDescriptor)descriptor;   String field = (String)validatorDescriptor.getArgs().get(FIELD_NAME);  if (field != null && field.trim().length() > 0)    return field;  else    return NOT_DEFINED;} Just check if the descriptor is a validator descriptor or not and then extract the field as shown in the preceding snippet. getVelocityParamsForEdit: This method defines the velocity parameters for the edit scenario, that is, when the user modifies the existing validator. Here we need both the options and the selected value. Hence we put both the custom fields' collection and the field name onto the velocity parameters. The second step is to define the velocity templates for each of the three aforementioned scenarios, namely, input, view, and edit. We can use the same template here for input and edit with a simple checking to keep the old field selected for the edit scenario. Let us look at the template: edit-fieldValidator.vm: Displays all custom fields and highlights the already selected one in edit mode. In input mode, the field variable will be null, and so nothing is pre-selected: <tr bgcolor="#ffffff">  <td align="right" valign="top" bgcolor="#fffff0">    <span class="label">Custom Fields :</span>  </td>  <td bgcolor="#ffffff" nowrap>    <select name="field" id="field">    #foreach ($cf in $fields)      <option value="$cf.name"        #if ($cf.name.equals($field)) SELECTED #end      >$cf.name</option>    #end    </select>    <br><font size="1">Select the Custom Field to be validated for NULL</font>  </td></tr> view-fieldValidator.vm: Displays the selected field: #if ($field)  Field '$field' is Required!#end The third step is to write the actual validator. The validator class should implement the Validator interface. All we need here is to implement the validate method. In our example, we retrieve the custom field value from the issue and throw an InvalidInputException if the value is null (empty): public void validate(Map transientVars, Map args, PropertySet ps)throws InvalidInputException, WorkflowException {    Issue issue = (Issue) transientVars.get("issue");    String field = (String) args.get(FIELD_NAME);      CustomField customField = customFieldManager.getCustomFieldObjectByName(field);     if (customField!=null){      //Check if the custom field value is NULL      if (issue.getCustomFieldValue(customField) == null){        throw new InvalidInputException("The field:"+field+" is             required!"); }    }  } The issue on which the validation is done can be retrieved from the transientVars map. customFieldManager is injected in the constructor as usual. All that is left now is to populate the atlassian-plugin.xml file with these components. We use the workflow-validator module, and it looks like the following block of code: <workflow-validator key="field-validator" name="Field Validator"  class="com.jtricks.FieldValidatorFactory">    <description>Field Not Empty Workflow Validator</description>     <validator-class>com.jtricks.FieldValidator</validator-class>     <resource type="velocity" name="view"location="templates/com/jtricks/view-fieldValidator.vm"/>    <resource type="velocity" name="input-parameters" location="templates/com/jtricks/edit-fieldValidator.vm"/>    <resource type="velocity" name="edit-parameters"location="templates/com/jtricks/edit-fieldValidator.vm"/></workflow-validator> Package the plugin and deploy it! Note that we have stored the role name instead of the ID in the workflow, unlike what we did in the workflow condition. However, it is safe to use the ID because administrators can rename the roles, which would then need changes in the workflows. How it works... After the plugin is deployed, we need to modify the workflow to include the validator. The following screenshot is how the validator looks when it is added initially. This, as you now know, is rendered using the input template: After the validator is added (after selecting the Test Number field), it is rendered using the view template and looks as follows: If you try to edit it, the screen will be rendered using the edit template, as shown in the following screenshot: Note that the Test Number field is already selected. After the workflow is configured, when the user goes to an issue and tries to progress it, the validator will check if the Test Number field has a value or not. It is at this point that the validate method in the FieldValidator class is executed. If the value is missing, you will see an error, as shown in the following screenshot:
Read more
  • 0
  • 0
  • 3380

article-image-html5-getting-started-paths-and-text
Packt
30 Nov 2011
10 min read
Save for later

HTML5: Getting Started with Paths and Text

Packt
30 Nov 2011
10 min read
(For more resources on this topic, see here.) Introduction This article is designed to demonstrate the fundamental capabilities of the HTML5 canvas by providing a series of progressively complex tasks. The HTML5 canvas API provides the basic tools necessary to draw and style different types of sub paths including lines, arcs, Quadratic curves, and Bezier curves, as well as a means for creating paths by connecting sub paths. The API also provides great support for text drawing with several styling properties. Let's get started! Drawing a line When learning how to draw with the HTML5 canvas for the fi rst time, most people are interested in drawing the most basic and rudimentary element of the canvas. This recipe will show you how to do just that by drawing a simple straight line. How to do it... Follow these steps to draw a diagonal line: Define a 2D canvas context and set the line style: window.onload = function(){  // get the canvas DOM element by its ID     var canvas = document.getElementById("myCanvas");  // declare a 2-d context using the getContext() method of the     // canvas object     var context = canvas.getContext("2d");  // set the line width to 10 pixels     context.lineWidth = 10;  // set the line color to blue     context.strokeStyle = "blue"; Position the canvas context and draw the line:  // position the drawing cursor    context.moveTo(50, canvas.height - 50); // draw the line    context.lineTo(canvas.width - 50, 50); // make the line visible with the stroke color    context.stroke(); }; Embed the canvas tag inside the body of the HTML document: <canvas id="myCanvas" width="600" height="250" style="border:1pxsolid black;"></canvas> How it works... As you can see from the preceding code, we need to wait for the page to load before trying to access the canvas tag by its ID. We can accomplish this with the window.onload initializer. Once the page loads, we can access the canvas DOM element with document. getElementById() and we can define a 2D canvas context by passing 2d into the getContext() method of the canvas object. We can also define 3D contexts by passing in other contexts such as webgl, experimental-webgl, and others. When drawing a particular element, such as a path, sub path, or shape, it's important to understand that styles can be set at any time, either before or after the element is drawn, but that the style must be applied immediately after the element is drawn for it to take effect, We can set the width of our line with the lineWidth property, and we can set the line color with the strokeStyle property. Think of this behavior like the steps that we would take if we were to draw something onto a piece of paper. Before we started to draw, we would choose a colored marker (strokeStyle) with a certain tip thickness (lineWidth). Now that we have our marker in hand, so to speak, we can position it onto the canvas using the moveTo() method: context.moveTo(x,y); Think of the canvas context as a drawing cursor. The moveTo() method creates a new sub path for the given point. The coordinates in the top-left corner of the canvas are (0,0), and the coordinates in the bottom-right corner are (canvas width, canvas height). Once we have positioned our drawing cursor, we can draw the line using the lineTo() method by defi ning the coordinates of the line's end point: context.lineTo(x,y); Finally, to make the line visible, we can use the stroke() method. Unless, otherwise specified, the default stroke color is black.To summarize, here's the typical drawing procedure we should follow when drawing lines with the HTML5 canvas API: Style your line (like choosing a colored marker with a specific tip thickness). Position the canvas context using moveTo() (like placing the marker onto a piece of paper). Draw the line with lineTo(). Make the line visible using stroke(). There's more... HTML5 canvas lines can also have one of three varying line caps, including butt, round, and square. The line cap style can be set using the lineCap property of the canvas context. Unless otherwise specified, the line cap style is defaulted to butt. The following diagram shows three lines, each with varying line cap styles. The top line is using the default butt line cap, the middle line is using the round line cap, and the bottom line is using a square line cap: Notice that the middle and bottom lines are slightly longer than the top line, even though all of the line widths are equal. This is because the round line cap and the square line cap increase the length of a line by an amount equal to the width of the line. For example, if our line is 200 px long and 10 px wide, and we use a round or square line cap style, the resulting line will be 210 px long because each cap adds 5 px to the line length. Drawing an arc When drawing with the HTML5 canvas, it's sometimes necessary to draw perfect arcs. If you're interested in drawing happy rainbows, smiley faces, or diagrams, this recipe would be a good start for your endeavor. How to do it... Follow these steps to draw a simple arc: Define a 2D canvas context and set the arc style: window.onload = function(){    var canvas = document.getElementById("myCanvas");    var context = canvas.getContext("2d");    context.lineWidth = 15;    context.strokeStyle = "black"; // line color Draw the arc: context.arc(canvas.width / 2, canvas.height / 2 + 40, 80, 1.1 *Math.PI, 1.9 * Math.PI, false);context.stroke();}; Embed the canvas tag inside the body of the HTML document: <canvas id="myCanvas" width="600" height="250" style="border:1pxsolid black;"></canvas> How it works... We can create an HTML5 arc with the arc() method which is defined by a section of the circumference of an imaginary circle. Take a look at the following diagram: The imaginary circle is defi ned by a center point and a radius. The circumference section is defi ned by a starting angle, an ending angle, and whether or not the arc is drawn counter-clockwise: context.arc(centerX,centerY, radius, startingAngle,            endingAngle,counterclockwise); Notice that the angles start with 0p at the right of the circle and move clockwise to 3p/2, p, p/2, and then back to 0. For this recipe, we've used 1.1p as the starting angle and 1.9p as the ending angle. This means that the starting angle is just slightly above center on the left side of the imaginary circle, and the ending angle is just slightly above center on the right side of the imaginary circle. There's more... The values for the starting angle and the ending angle do not necessarily have to lie within 0p and 2p. In fact, the starting angle and ending angle can be any real number because the angles can overlap themselves as they travel around the circle. For example, let's say that we defi ne our starting angle as 3p. This is equivalent to one full revolution around the circle (2p) and another half revolution around the circle (1p). In other words, 3p is equivalent to 1p. As another example, - 3p is also equivalent to 1p because the angle travels one and a half revolutions counter-clockwise around the circle, ending up at 1p.Another method for creating arcs with the HTML5 canvas is to make use of the arcTo() method. The resulting arc from the arcTo() method is defi ned by the context point, a control point, an ending point, and a radius: context.arcTo(controlPointX1, controlPointY1, endingPointX,              endingPointY, radius); Unlike the arc() method, which positions an arc by its center point, the arcTo() method is dependent on the context point, similar to the lineTo() method. The arcTo() method is most commonly used when creating rounded corners for paths or shapes. Drawing a Quadratic curve In this recipe, we'll learn how to draw a Quadratic curve. Quadratic curves provide much more flexibility and natural curvatures compared to its cousin, the arc, and are an excellent tool for creating custom shapes. How to do it... Follow these steps to draw a Quadratic curve: Define a 2D canvas context and set the curve style: window.onload = function(){    var canvas = document.getElementById("myCanvas");    var context = canvas.getContext("2d");    context.lineWidth = 10;    context.strokeStyle = "black"; // line color Position the canvas context and draw the Quadratic curve: context.moveTo(100, canvas.height - 50);    context.quadraticCurveTo(canvas.width / 2, -50, canvas.width- 100, canvas.height - 50);    context.stroke();}; Embed the canvas tag inside the body of the HTML document: <canvas id="myCanvas" width="600" height="250" style="border:1pxsolid black;"></canvas> How it works... HTML5 Quadratic curves are defined by the context point, a control point, and an ending point: context.quadraticCurveTo(controlX, controlY, endingPointX,      endingPointY); Take a look at the following diagram: The curvature of a Quadratic curve is defined by three characteristic tangents. The first part of the curve is tangential to an imaginary line that starts with the context point and ends with the control point. The peak of the curve is tangential to an imaginary line that starts with midpoint 1 and ends with midpoint 2. Finally, the last part of the curve is tangential to an imaginary line that starts with the control point and ends with the ending point. Drawing a Bezier curve If Quadratic curves don't meet your needs, the Bezier curve might do the trick. Also known as cubic curves, the Bezier curve is the most advanced curvature available with the HTML5 canvas API. How to do it... Follow these steps to draw an arbitrary Bezier curve: Define a 2D canvas context and set the curve style: window.onload = function(){    var canvas = document.getElementById("myCanvas");    var context = canvas.getContext("2d");    context.lineWidth = 10;    context.strokeStyle = "black"; // line color    context.moveTo(180, 130); Position the canvas context and draw the Bezier curve: context.bezierCurveTo(150, 10, 420, 10, 420, 180);   context.stroke();}; Embed the canvas tag inside the body of the HTML document: <canvas id="myCanvas" width="600" height="250" style="border:1pxsolid black;"></canvas> How it works... HTML5 canvas Bezier curves are defined by the context point, two control points, and an ending point. The additional control point gives us much more control over its curvature compared to Quadratic curves: context.bezierCurveTo(controlPointX1, controlPointY1,    controlPointX2, controlPointY2,    endingPointX, endingPointY); Take a look at the following diagram: Unlike Quadratic curves, which are defined by three characteristic tangents, the Bezier curve is defined by five characteristic tangents. The first part of the curve is tangential to an imaginary line that starts with the context point and ends with the fi rst control point. The next part of the curve is tangential to the imaginary line that starts with midpoint 1 and ends with midpoint 3. The peak of the curve is tangential to the imaginary line that starts with midpoint 2 and ends with midpoint 4. The fourth part of the curve is tangential to the imaginary line that starts with midpoint 3 and ends with midpoint 5. Finally, the last part of the curve is tangential to the imaginary line that starts with the second control point and ends with the ending point.
Read more
  • 0
  • 0
  • 3902
article-image-null-8
Packt
27 Nov 2011
2 min read
Save for later

Unity books now added to the e-learning Library in PacktLib

Packt
27 Nov 2011
2 min read
PacktLib is pleased to announce the addition of Unity books to its e-Learning library. As teaching Unity is becoming more and more popular, and following feedback from e-Learning library subscribers, Packt has added Unity books to the e-Learning library to satisfy educators. The dedicated e-Learning library in PacktLib is a beneficial resource for administrators, teachers and now also for game developers to learn about the ways in which to study books in order to enhance their capabilities and acquire knowledge in their respective work projects and areas of interests through electronic means. At no extra cost, subscribers to the e-Learning subscription on PacktLib will now get access to Packt’s Unity books. This includes access to Packt’s bestselling Unity Game Development Essentials, which is being relaunched for 3.x in November. Packt’s Unity books allow readers to understand the basic principles of game design before further advancing into learning about the game development techniques by using step-by-step guides to simply illustrate the process of creating a game. Furthermore, some books in this series will enable readers to use the free Unity 3D game engine to build games. Packt’s Unity books also cover tips and tricks, innovative ideas and coding samples that support the development of sophisticated gaming visuals and sequences. With more than 35 books in this subject area, subscribers of the e-learning library will have full access to an archive of up-to-date information on relevant technologies ranging from Moodle, Sakai, Alice, Mahara, and Unity. Moreover, future books added to the library will also be made available to subscribers as long as they have a subscription. This resource will give educators and game developers the tools to organise projects effectively and create fun games as well as the ability to search for specific information on the PacktLib platform. For more information, please visit http://packtlib.packtpub.com/
Read more
  • 0
  • 0
  • 1474

article-image-null-10
Packt
27 Nov 2011
2 min read
Save for later

PacktLib now Offers a Joomla! Library

Packt
27 Nov 2011
2 min read
Packt has today announced a new subscription on PacktLib for Joomla! developers. Housing 26 books, this library will enable Joomla! developers to get up and running quickly, as well as extend their skills and knowledge to become serious professionals. Recently announced as the winner of the best 2011 Open Source CMS, a resurgent Joomla!, now with a six month development cycle, has proved itself to be one of the leading open source content management systems on the market. The Joomla! library consists of information relating to the development of building media rich, dynamic and interactive Joomla! websites. The extensive variety of topics within this open source technology includes eCommerce, search engine optimisation, content administration, multimedia, themes and templates, creating a social network with JomSocial, enhancing a Joomla! site with JavaScript and jQuery, interacting with users by utilising ChronoForms, web security and much more. This source of Joomla! books will enable readers to build powerful websites and online applications by way of add-ons, extensions and plugins in addition to understanding the framework in which this technology is based on. This resource is ideal for beginners who want to learn more about building a functional and well-designed website. Many books in this library provide step-by-step instructions as well as examples to guide readers in setting up a functional and visually appealing website. In addition to this, those who have experience with using Joomla! can find more advanced features to install onto their website making this library a comprehensive resource on Joomla! for readers with different skill levels. Packt was the first publisher to bring an English book on Joomla! to market and has long been a supporter of Joomla! through the Open Source Royalty scheme. With 26 books on this technology, subscribers of the Joomla! library will have full access to an archive of up-to-date information on the content management system. Moreover, future books added to the library will also be made available to subscribers as long as they have a subscription. This resource will give site administrators the tools to create and develop successful websites as well as the ability to search for specific information and find answers to problems on the PacktLib platform. For more information, please visit http://packtlib.packtpub.com/
Read more
  • 0
  • 0
  • 6324
Modal Close icon
Modal Close icon