Scrolling in SproutCore: Part 2

written by Tim Evans

4 Comments

Continued from last week’s post “Scrolling in SproutCore”. Tim presents his solution for making SC.ScrollView feel awesome.


I began discussing possible solutions to the problem with Colin Campbell, who pointed me in the direction of Cappuccino as a reference implementation. Cappuccino’s scroll views were buttery smooth and offered all of the benefits that SproutCore needs. So, I began investigating.

This is what I found:

See that blue box in the center of the screen – the one that I pointed an arrow to? This is how Cappuccino applications take scroll events. Normally, you’ll never see this because it has an opacity of 0, and its purpose is to swallow scroll events. Yes. This little element, which I’ll call the scroll catcher for the remainder of this discussion, takes in scroll events and then creates normalized events from it.
Continue reading

Scrolling in SproutCore

written by Tim Evans

3 Comments

Converting native widgets into SproutCore compatible widgets can be an adventure, especially if the browser vendors don’t agree on the events that the widget produces. Scrollable elements are one of those things.

For those of you who find SproutCore’s ScrollView insufferable on various platforms because it’s not scrolling how you expect it to, this should shed some light on how really hard the problem actually is. And, hopefully you’ll be satisfied with the solution that I propose.

First, let me answer the question of why… Why, that is, SproutCore needs its own ScrollView. There are two primary reasons for this: cosmetic and performance.

The cosmetic reason is theming. SproutCore has the ability to skin pretty much everything in your application, including scrollbars. This gives a consistent look and feel across platforms and eases the headache of UI consistency. However, some people want their applications to have the native look and feel. The current implementation of SC.ScrollView doesn’t allow that. This can be a turnoff, especially when mixing-and-matching SC.ScrollView and native scroll views. It creates inconsistency, which leads to bad user interaction.

SproutCore prides itself on being able to render gigantic lists of items without hosing your browser. It does this by incrementally rendering the list. This means that what you see is all there is with SC.ListView. Anything you can’t see is not actually rendered in the DOM. Implementing this requires SproutCore to know about the clipping frame (the rectangle that gives the information on what’s currently visible). To get the clipping frame, SproutCore needs to observe when scrolling happens. Hence, SC.ScrollView.

Now for a quick dig into the internals of how 1.x SC.ScrollView works in “desktop” mode, so when we start looking at our solutions, we know what stuff is changing.

I’m going to take it backwards from where the scrollTop and scrollLeft are set in the DOM being controlled by SC.ScrollView. For those of you who’d like to follow along, I’m looking at the adjustElementScroll function in scroll.js in the desktop framework.

I’m going to break this down, ’cause this function contains the core of what makes SC.ScrollView tick.

1
2
3
4
5
6
7
8
9
  /** @private
    Called at the end of the run loop to actually adjust the scrollTop
    and scrollLeft properties of the container view.
  */
  adjustElementScroll: function() {
    var container = this.get('containerView'),
        content = this.get('contentView'),
        verticalScrollOffset = this.get('verticalScrollOffset'),
        horizontalScrollOffset = this.get('horizontalScrollOffset');

Pretty self-explanatory, continuing on…

1
2
3
4
5
6
7
8
9
10
11
12
    // We notify the content view that its frame property has changed
    // before we actually update the scrollTop/scrollLeft properties.
    // This gives views that use incremental rendering a chance to render
    // newly-appearing elements before they come into view.
    if (content) {
      // Use accelerated drawing if the browser supports it
      if (SC.platform.touch) {
        this._applyCSSTransforms(content.get('layer'));
      }
 
      if (content._viewFrameDidChange) { content._viewFrameDidChange(); }
    }

Here’s the first interesting bit. Ignoring the accelerated drawing, which is for the touch version of SC.ScrollView, we have the last line calling content._viewFrameDidChange. Hmm. What does that do?
Continue reading

Structuring Your SproutCore Application: Part 1

written by Colin Campbell

8 Comments

This is the first in a series of posts that recap Colin’s talk at the San Francisco Meetup 6/14 and go into some detail about structuring a SproutCore application. Stay tuned for more posts in this series, and, as always, we’re listening to your feedback– let us know where you’re confused or what you want to learn more about.


Building applications that scale well is very important, but “scaling well” isn’t limited to ensuring your servers can handle the load. It is equally important to structure your application so that you can easily maintain your code and introduce new functionality without needing to rewrite significant portions. There are libraries provided by SproutCore, like the statechart library, that will help your application grow smoothly.

Let’s dive into how to structure your SproutCore application so that it’s maintainable and can grow with your project. In Part 1, I’ll be covering how to set up your application so that you will be able to add functionality later with minimal refactoring.

Introduction

We’ll be going through an application I built for the SproutCore San Francisco Meetup earlier this month. It is available on Github.

To get started, let’s generate the application using the following command:

sc-init Contact --template

As you can see, we’ve named our application `Contact` and we’re choosing to use the new HTML-based application structure. We’re going to be developing this SproutCore 1.6 application so that we can upgrade it to the SproutCore 2.0 stream eventually. That means using `SC.TemplateView` for all of our content views, and limiting our usage of other views that rely on layout.
Continue reading

Get Up to Date with the SproutCore Meetups!

written by Madeleine Douglas

Comments Off

Have you been to a SproutCore Meetup yet? If you haven’t, now is the time!

Since February, we have grown from having 3 active meetups in the US to having 10 internationally– and several more in the works. We’re excited by the energetic response we’ve received from you, the SproutCore community, and hope many of you are able to come and share in the awesomeness (and swag!).

We’re always looking for ways to involve more community members in the user groups. If you’re interested in speaking at any of the existing meetups, or if you’re interested in starting a meetup in your neck of the woods, email us at community@sproutcore.com– we’d love to have you!

In the meantime, we want to share some talks that have been given at recent meetups: The Future of SproutCore, by Tom Dale at the Chicago meetup on May 24, and Structuring Teams to Build Large-Scale SproutCore Apps, given by Peter Bergstrom to the San Francisco meetup on June 14th.

On the 14th, the SF group was also lucky enough to hear a great talk by Colin Campbell on the ABCs of Building a SproutCore App. Unfortunately, we had a bit of a hiccup recording Colin’s talk, but stay tuned for a blog post next week where he’ll take you through the code examples he showed.

Until then, you can find the code from his presentation here.


In this talk, The Future of SproutCore, Tom Dale explains some of the changes that are coming in SproutCore 2.0, and hopefully answers a few questions you may have about where SproutCore is headed.

Bear with us on the audio for the first portion; the echo goes away quickly :)


Watch here as Peter Bergstrom expands on his blog post about structuring teams and division of labor on large-scale SproutCore projects.


We hope you found these recordings helpful– and next time, we hope to see you in person!

Dispatches From The Edge: Handlebars Without Spans

written by Greg Moeck

Comments Off


As more people have been using templates to map the state of their views into the DOM, a couple of questions have continually come up. In this week’s Dispatch, I want to focus on how SC.TextField solves one of the common questions and offer some advice on building similar custom views.

Let’s first specify the common question: How would one go about implementing something like a textarea tag? Just about everyone tries to do it like this:

<textarea>{{content}}</textarea>

You would like it to render something like this:

<textarea>Some Content</textarea>

But instead, SproutCore outputs something that looks like the following:

<textarea><span>Some Content</span></textarea>

Why would SproutCore wrap your content inside of the span tag? Because the Handlebars template isn’t only responsible for the initial rendering, it’s also keeping that rendered content in sync with the state of your view. Because of this, it needs to be able to target an element inside of the DOM to replace when the state of your view changes. So SproutCore inserts that span tag into the rendered DOM so that it can later change the DOM when content changes.
Continue reading

SproutCore 1.6 Released

written by Peter Wagenet

3 Comments

We’re pleased to announce that SproutCore 1.6 is now out!

SproutCore 1.6 is largely a bug fix release aiming to help provide a more stable experience. If you’re using SproutCore 1.5 it should be a relatively straight-forward upgrade.

For more information on the changes, see the Abbot changelog and the framework changelog.

Upgrade now via package or, if you installed via RubyGems, run gem install sproutcore. Enjoy!

By the way, we’re still on a six week release schedule so that means we’re planning to release 1.7 in mid-to-late July. Keep an eye out for more news on 1.7 in the coming weeks.

Statecharts in SproutCore

written by Joachim Haagen Skeie

25 Comments

In their most simple form, statecharts are a way to structure your application into logical states. A statechart does not need to be implemented in your application’s code; but it is easier to adhere to the statechart you lay out if you are able to create or use a framework that defines:

  • what is possible to do within a state
  • how the application can transition from one state to another
  • and finally what needs to be set up and torn down upon state entry and state exit.

From SproutCore Version 1.5 and onwards, there is a fantastic Statechart framework built right into the library itself– conveniently called SC.Statechart.

To Statechart or Not to Statechart?

For me, there are a couple of main reasons to use statecharts. First, having to sit down and think about your application’s possible states makes you think long and hard about the actual design of your application. Second, splitting a large application into logical (and smaller) states makes it easier to break functional requirements down into manageable parts when it is time to plan and develop the application.

As a final bonus, you end up with a finished application that has one killer feature: separation of concerns between application domains. That last part alone should make you want to invest in using statecharts for your application: cleaner code and less spaghetti.

The State of the Game

There are many ways to structure a statechart application. The statechart needs to have one and only one root state, which you can think of as the initial state of your application.

There are a number of key factors that needs to be included in each state, so that the states can be combined into a statechart.

  • Each state needs to have exactly one clearly defined entry point
  • Each state needs to have at least one clearly defined exit point (the possible transitions available)
  • Each state needs to be able to set up everything required within that state upon state entry
  • Each state needs to be able to tear down anything that is state-specific upon state exit

Note that the above can be considered my guidelines. It’s most certainly possible to break any of the above requirements inside your statechart implementation– however, be prepared that the end result might be messy/spaghetti code, no clear separation of concerns, or worse, both.

An added bonus of using SC.statechart is that you will also be able to build an application where the routes that the user can travel through your application is made explicit in both design and code.

Statecharts and the MVC Model

Since Statecharts will make up a large portion of your application’s architecture, where does it fit into the SproutCore MVC model? Will a Statechart-built application really be something like an MVCS (Model-View-Controller-Statechart) model?

The answer to the first question is that Statecharts fits in beautifully with the SC MVC model. The answer to the MVCS question is: it depends on your viewpoint.

Without statecharts, the SproutCore MVC model looks like the diagram below.


Continue reading

The Run Loop: Part 1

written by Tyler Keating

8 Comments

The following post cuts to the very core, pun intended, of SproutCore: the Run Loop.

What is a Run Loop?

In order to ensure that we’re all talking about the same thing, here’s the definition from Wikipedia:

In computer science, the event loop, message dispatcher, message loop, message pump, or run loop is a programming construct that waits for and dispatches events or messages in a program. It works by polling some internal or external “event provider”, which generally blocks until an event has arrived, and then calls the relevant event handler (“dispatches the event”).

That’s a bit of a high-level definition, but I’ll try to expose the “bare metal” of SproutCore’s Run Loop enough so that it makes sense not only theoretically, but practically too.

What is the Run Loop?

In the context of SproutCore, the Run Loop is a function that coordinates code, key-value notifications, and timers within your application. Typically, a new Run Loop will automatically be started by SproutCore in response to the browser firing certain events, but a new Run Loop can be manually started at any time by placing your code between a `SC.RunLoop.begin()` statement and a `SC.RunLoop.end()` statement.

At this point, you may be thinking, “All right, smart guy, it’s easy to make general statements like ‘firing certain events’, but what events exactly?”. All right, smart reader, heaven forbid we leave anything to ambiguity. Let us look at the events that SproutCore listens for.
Continue reading