How to intercept the fling progress in CardScrollView for GDK? - google-glass

When a fling happens in a CardScrollView, I see the "zoomed out" view of a long list of cards scrolling by. This part works fine as in the code below:
mCardScrollView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (mSimulatedScrollBar != null)
mSimulatedScrollBar.setScrollPosition(position);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
However, the problem is I don't receive any update when this is happening in the OnItemSelectedListiner until the fling stops. The problem this causes is the list scrolls but until it "settles" I don't get any update on the list progress and thus can't respond in the foreground with a progress view.
There are a number of listeners and protected methods for CardScrollView, do any provide this functionality?

There currently aren't any methods or listeners that give you access to the finer scroll details of the view — only events when the user settles on a card or begins scrolling.
If you'd like to see a feature like this, please file a request in our issue tracker.

Related

QtWebView - How to enable scrolling of page and scrolling of elements in a page (e.g. Google Maps)

I've run into a bit of an issue related to a whitelist Web Browser my company has been developing / maintaining for one of our product lines. The browser runs on top of Qt 4.8.6, using qtwebkit (Migration to 5.X would be ideal, but the embedded Linux OS we're using is too old to support the newer versions based on our testing, and upgrading to a newer OS is too costly to us / our customers). The primary interface to the browser is a 6x8 touchscreen, mounted inside an aircraft cockpit.
For sites that have things like scrollable/embedded maps (ex. Google Maps), the users of the browser want the ability to drag the entire page when they are selecting something outside of the map, and drag just the map (without the entire page scrolling) when the map is selected (Ala most of the popular mobile browsers).
Thus far, I am able to do one or the other, but not both:
When I hook mouse handlers into a QWebView or QGraphicsWebView, I can turn the cursor into a hand and very easily support dragging of the entire web page. However, that inhibits the page's ability to handle the mouse events for when a user is pulling over a map (i.e. When a user drags over a map, it drags the entire page without moving the map).
When I don't add in the hooks to handle mouse events, things like maps are scrollable by grapping/dragging them, but of course the user loses the ability to drag the entire page.
Right now, the browser uses the later, with scroll bars disabled and a directional-arrow overlay to allow the user to scroll the entire page (as the display size is limited, and scrollbars take up too much space when they are sized large enough for the user to interact with them)...but this is not ideal.
My Question: Is there any easy way to make it so that the page, and elements in a page, can be scrolled seamlessly?
Thanks!
Rob
Seems to me like you need to check if you are over such a map and ignore(pass along) the event in that case. I think you should be able to do something like this:
bool GraphicsWebView::isOverMap(QPoint pos) {
QWebPage* webPage = this->page();
if (webPage) {
QWebFrame* webFrame = webPage->frameAt(pos);
if (webFrame) {
QString selectorQuery = "#map-canvas"; // Based on https://developers.google.com/maps/tutorials/fundamentals/adding-a-google-map
QList<QWebElement> list = webFrame->findAllElements(selectorQuery).toList(); // Find all the maps!
foreach(QWebElement element, list) {
if (element.geometry().contains(pos)) {
return true; // Cursor is over a map
}
}
}
}
return false; // No match
}
Obviously this is a pretty specific function but there is probably a way to come up with a better selector query that will apply to all those kinds of QWebElement.
Assuming you hook mouse events by subclassing QGraphicsWebView and reimplementing void mouseMoveEvent(QGraphicsSceneMouseEvent * event), I suggest you do something like:
void GraphicsWebView::mouseMoveEvent(QGraphicsSceneMouseEvent* event) {
if (isOverMap(mapFromScene(event->scenePos()).toPoint())) { // We got a map!
event.ignore(); // Clear the accept flag
return; // Return, we're done here
}
handleMoveView(); // Not over any maps, let's scroll the page
}
This part of the doc explains how events are handled with regard to the topmost item. I especially recommend you read the third paragraph.
Hope that helps!
EDIT: Did a bit more research and it looks like something like that could be more generic:
graphicsView.focusItem()->flags().testFlag(QGraphicsItem::ItemIsMovable);
It's at the very least worth investigating as a replacement to isOverMap()
EDIT: Gotcha, here is something you can try then.
Start by subclassing QGraphicsSceneMouseEvent and add a signal called void destroyedWithoutAccept() that's emitted in the destructor if the event has not been accepted.
Then modify mouseMoveEvent to look like this:
void GraphicsWebView::mouseMoveEvent(QGraphicsSceneMouseEvent* event) {
MyEvent myEvent = new MyEvent(event); // Copy event
event.accept(); // accept original event
connect(myEvent, SIGNAL(destroyedWithoutAccept),
this, SLOT(handleMoveView)); // Callback if unused
QGraphicsWebView::mouseMoveEvent(myEvent); // Pass it to Base class
}
If that works, it might introduce a bit of delay if deleteLater is used to destroy it. But in that case reimplement it as well.

ActionBar owner in Mortar

In Mortar, I'm curious how people are handling the ActionBar if it changes based on the screen being shown. Say, for instance, that you want to change the ActionBar title or actions if a certain screen is being shown.
Injecting an Activity seems like a terrible idea, and you want a presenter (or view, I suppose) to be able to get the correct action bar after screen rotation.
Is there a particularly effective pattern here that I'm missing? All the solutions I had work, but are more awkward than I hoped.
For actions, the flow-sample application's MainActivity includes:
public boolean onCreateOptionsMenu(Menu menu) {
...
Object screen = AppFlow.get(this).getBackstack().current().getScreen();
...
public void go(Backstack nextBackstack, Flow.Direction direction, Flow.Callback callback)
Screen screen = (Screen) nextBackstack.current().getScreen();
...
Both methods are aware of the screen to be displayed. The actions are defined in onCreateOptionsMenu(), the title in go(). The issue is that all this is located in the MainActivity.
What you could do is create a ActionEnabledScreen interface with a method:
public boolean onCreateOptionsMenu(Menu menu);
And a TitleEnabledScreen interface with a method:
public void getTitle();
Your activity would then look like this:
public boolean onCreateOptionsMenu(Menu menu) {
...
Object screen = AppFlow.get(this).getBackstack().current().getScreen();
if (screen instanceof ActionEnabledScreen) {
return ((ActionEnabledScreen)screen).onCreateOptionsMenu(menu);
}
...
public void go(Backstack nextBackstack, Flow.Direction direction, Flow.Callback callback)
Screen screen = (Screen) nextBackstack.current().getScreen();
if (screen instanceof TitleEnabledScreen) {
setTitle(((TitleEnabledScreen)screen).getTitle());
}
...
Note that I didn't run the above code, so it might not compile / run, but I hope you see the idea. The aim is to avoid having MainActivity expand linearly as you implement new screens, and avoid at all costs having to reference you screen classes directly in it.
Hope this helps!

How to force a LiveCard to be visible until dismissed

I'm building a heads up display for OBD data (speed, RPM, throttle position etc.) using Glass.
I am using a LiveCard to display the HUD, but like all cards it fades away after a few seconds as Glass puts the display to sleep.
Is there a way to force the card to remain visible until it's dismissed? A HUD display isn't very useful if it keeps needing to be woken up.
The code thus far is here: https://github.com/mpicco/glass-obd-hud.
Thanks,
Marty
I'd would recommend using an Immersion + the FLAG_KEEP_SCREEN_ON flag or getting a partial wakelock within your Service.
From the Android documentation:
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag");
wl.acquire();
// ..screen will stay on during this section..
wl.release();
If you do use the wakelock solution, do not forget to release it once your Service is stopped.
The way I've done this is inside the activity that I wish to keep the screen on for, I've added a window parameter like so:
public class MyActivity extends Activity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}
The power manager service would likely work just as well, but this way when the user destroys my activity or other such things, I don't have to worry about maintaining state.

Movement of elements in GEF editor not working

I am currently building an editor with Eclipse GEF. It is possible to add new parts via the editor and rename them.
However I have a little problem with the moving of the elements. When dragging them with the mouse they are not moved when I release the mouse and the element doesn't collide with another one.
The positions of the elements are stored in an EMap (the model is made with EMF). Changes in the view are saved with the put method of the map.
While going through it with the debugger I noticed that the command is executed, but the view is not refreshed yet.
I added an adapter to the model, but its notifyChanged is not called from the system.
public class ViewAdapter implements Adapter {
#Override
public void notifyChanged(Notification notification) {
refreshVisuals();
}
}
The ViewAdapter is registered in the activate method of the EditPart.
What could it be?
As you are working with a map the normal Adapter interface won't work, because it only listens to adds or removals of map entries.
If you want to listen on changes of map elements, you should use an EContentAdapter instead:
public class ViewAdapter extends EContentAdapter {
#Override
public void notifyChanged(Notification notification) {
refreshVisuals();
super.notifyChanged(notification);
}
}
It is important that you call the super method so the notifications of the map entries are forwared to the map itself.

Model View Controller Design pattern Code Example

I was studying the Model-View-Controller design pattern and i understand the concept behind the pattern theorotically, but I wanted to get a peek at how one would actually put it to practice.
Wikipedia mentions Wt - Web toolkit, CppCMS and some other standard implementations which use the pattern however I have not been familiar with these, and I was just hoping and
will be really grateful If anyone can provide some sample code(hopefully C++) which implements the pattern and explains the theory of the pattern being put to practice.
Here's a quick example I made (didn't try compiling it, let me know if there's errors):
class Button; // Prewritten GUI element
class GraphGUI {
public:
GraphGUI() {
_button = new Button("Click Me");
_model = new GraphData();
_controller = new GraphController(_model, _button);
}
~GraphGUI() {
delete _button;
delete _model;
delete _controller;
}
drawGraph() {
// Use model's data to draw the graph somehow
}
...
private:
Button* _button;
GraphData* _model;
GraphController* _controller;
};
class GraphData {
public:
GraphData() {
_number = 10;
}
void increaseNumber() {
_number += 10;
}
const int getNumber() { return _number; }
private:
int _number;
};
class GraphController {
public:
GraphController(GraphData* model, Button* button) {
__model = model;
__button = button;
__button->setClickHandler(this, &onButtonClicked);
}
void onButtonClicked() {
__model->increaseNumber();
}
private:
// Don't handle memory
GraphData* __model;
Button* __button;
};
Ignoring the implementation of Button, basically this program will use GraphGUI to display a graph that will change when a button is pressed. Let's say it's a bar graph and it will get taller.
Since the model is independent of the view (the button), and the controller handles the communication between the two, this follows the MVC pattern.
When the button is clicked, the controller modifies the model via the onButtonClicked function, which the Button class knows to call when it is clicked.
The beauty of this is since the model and view are completely independent, the implementation of each can drastically change and it won't affect the other, the controller might simply have to make a few changes. If the model in this case calculated some result based off some database data, then clicking the button could cause this to happen, but the button implementation wouldn't have to change. Or, instead of telling the controller when a click occurs, maybe it can tell the controller when the button is moused-over. The same changes are applied to model, regardless of what triggered the changes.
A simple text editor could be designed based on MVC. Think of the string class as the model, where data is stored. We might have a class called SimpleTextView which displays the text in the string attached to it, as it is. A class called KeyboardEventHandler can act as the controller. The controller will notify the view about new keyboard events. The view in turn modifies the model (like appending or removing text). The changes in the model is reflected on all views attached to it. For instance, there might be another view called HtmlView attached to the string object manipulated from within the SimpleTextView. If the user enters valid HTML tags in the SimpleTextView, the HtmlView will display the formatted output - real-time.
There are couple of complete MVC examples, plus discussion, in ch 2 of an introduction to programming in Python 3.x that I wrote (I've not completed ch 3 etc., that project's been on ice for some time -- Python community really like angry swarm of bees when discovered I'd written that Python was perhaps not suitable for very large scale development, so it became difficult to get sensible feedback). It's available in PDF format from Google Docs. I don't know how well it maps to common MVC implementations, I was mostly concerned with getting the general idea across. :-)
Cheers & hth.,
PS: There's a nice table of contents in the PDF file but Google Docs doesn't show it. You'd need to dl and use Foxit or Acrobat or some other PDF viewer. I think there's a separate viewable TOC at Google Docs, though, haven't checked and don't remember whether updated.
PPS: Forgot to mention, the MVC image processing example near the end has nice pic of Lena Söderberg! :)
Code is the best approach to understand and learn Model View Controller:
Here is a simple JS example (from Wiki)
/** Model, View, Controller */
var M = {}, V = {}, C = {};
/** Model stores data */
M.data = "hello world";
/** View controls what to present */
V.render = (M) => { alert(M.data); }
/** Controller bridges View and Model */
C.handleOnload = () => { V.render(M); }
/** Controller on Windows OnLoad event */
window.onload = C.handleOnload;
Here is a detailed post in C/C++
Model-View-Controller Explained in C++