I'm trying to create maps application like the WP7 Maps. I know that in WPF it's simple to manage map canvases gestures through MatrixTransform, but WP7's version of MatrixTransform is less functional.
Is there any patterns how to manage all ManipulationDelta events to:
Zoom in and zoom out. Now I make it like that:
var maxScale = Math.Max(
args.DeltaManipulation.Scale.X,
args.DeltaManipulation.Scale.Y);
if (Math.Abs(maxScale - 0) > 0.0001 &&
((maxScale < 1 && _scale.ScaleX > MIN_SCALE) ||
(maxScale > 1 && _scale.ScaleX < MAX_SCALE)))
{
_scale.ScaleX *= maxScale;
_scale.ScaleY *= maxScale;
}
where _scale = new ScaleTransform(); and it has to be improved to manage position of canvas
Move map by finger. By first step it's look like:
_translation.X += args.DeltaManipulation.Translation.X
* _scale.ScaleX;
_translation.Y += args.DeltaManipulation.Translation.Y
* _scale.ScaleX;
where _translation = new TranslateTransform();
Make some dynamic after Pan, Pinch and Stretch
no current implementation, but I'm looking at ManipulationCompleted, where add some code to "continue" gestures in more natural way.
I'm looking for typical solution to manage this features, may be my way is wrong and not through ManipulationDelta
After a little research I've decided to use this behaviour to add multitouch http://gallery.expression.microsoft.com/MultiTouch/
If something goes wrong I can just see at reflected code and create something like that
Related
This is a modification of this question. I have an isometric grid of images and curious - is it possible to scroll it in free ways (diagonals included). Currently I have this code and it's possible to scroll 2D:
val scrollStateHorizontal = rememberScrollState()
val scrollStateVertical = rememberScrollState()
Box(
modifier = Modifier
.horizontalScroll(scrollStateHorizontal)
.verticalScroll(scrollStateVertical)
) {
for (i in 0..8) {
for (j in 0..7) {
val start = (y % 2 * 0.5 + x) * width
val top = i * height * 0.5
Image(modifier = Modifier.padding(start = start.dp, top = top.dp), painter = ...)
}
}
}
What is interesting:
Can I scroll diagonally?
How can I optimize it (memory consumption, etc.)? Maybe I should use LazyHorizontalGrid including LazyVerticalGrid/LazyColumn/LazyRow?
It seems, LazyHorizontalGrid can't be modified simply adding Modifier.verticalScroll. And it has a lag for first few seconds of scrolling (maybe for caching items) while simple Box scrolling acts smoothly from the start.
As of now, there's no official support for this, as far as I know. The only way you could implement this as of the current stable, is by using LazyLayout Composable, or by modifying the verticalScroll (or horizontal) Modifiers. Read here. It is a recent addition to the APIs so the documentation is very scarce. You'll have to look it up on the web for sample implementations.
"Read here"
as the Toolbar or Titlearea on scroll animation feature is referenced in the last section of the Toolbar API, and also in this great video tutorial (starting at about min 45), the animation works well under given circumstances.
I was not able to find any documentation about what these have to be, however I found one circumstance, in which it does not work. Here is a working example to demonstrate the problem:
Form hi = new Form("Title", new BoxLayout(BoxLayout.Y_AXIS));
EncodedImage placeholder = EncodedImage
.createFromImage(Image.createImage(hi.getWidth(), hi.getWidth() / 5, 0xffff0000), true);
URLImage background = URLImage.createToStorage(placeholder, "400px-AGameOfThrones.jpg",
"http://awoiaf.westeros.org/images/thumb/9/93/AGameOfThrones.jpg/400px-AGameOfThrones.jpg");
background.fetch();
Style stitle = hi.getToolbar().getTitleComponent().getUnselectedStyle();
stitle.setBgImage(background);
stitle.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL);
stitle.setPaddingUnit(Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS);
stitle.setPaddingTop(15);
// hi.setLayout(new BorderLayout()); // uncomment this for the animation to break
Container contentContainer = new Container(BoxLayout.y());
contentContainer.setScrollableY(true);
// add some elements so we have something to scroll
for (int i = 0; i < 50; i++)
contentContainer.add(new Label("Entry " + i));
hi.add(contentContainer);
// hi.add(BorderLayout.CENTER, contentContainer); // use this line instead of the above for the animation to break
ComponentAnimation anim = hi.getToolbar().getTitleComponent().createStyleAnimation("Title", 200);
hi.getAnimationManager().onTitleScrollAnimation(anim);
hi.show();
With my current app and the codesample from the Toolbar API (which is roughly adapted here), I found out that the onScrollAnimation event is not being called, when a scroll occurs inside a BorderLayout. Even when I have a separate container, which is not the contentpane itself, and I set setScrollableY(true); to true, the animation works properly. The animation stops working, when this very container is put into Center of the Form, via Borderlayout. in the example above, the layout is exactly the same, as there are no other components in other areas of course, but it breaks the animation.
How to solve this? In my app, I have the need for a BorderLayout but still want to use this cool feature. Also, this is a very un-intuitive feature, if it works for some, but not all layouts. It should be completely layout-agnostic and work in every case.
Thank you.
The adapter is bound to the forms content pane scrolling so it won't work if you have a border layout in here. In that case scrolling isn't detected because the code just isn't aware of the scrolling. It would need to track the scrolling of any component in the UI to detect that scrolling.
as hinted by Shai, the solution is the following:
hi.setLayout(new BorderLayout());
Container contentContainer = new Container(BoxLayout.y());
contentContainer.setScrollableY(true);
// add some elements so we have something to scroll
for (int i = 0; i < 50; i++)
contentContainer.add(new Label("Entry " + i));
hi.add(BorderLayout.CENTER, contentContainer); // use this line instead of the above for the animation to break
ComponentAnimation anim = hi.getToolbar().getTitleComponent().createStyleAnimation("Title", 200);
hi.getAnimationManager().onTitleScrollAnimation(contentContainer, anim);
instead of using the onTitleScollAnimation to just add the animation, provide your own scrollable "body" or content container as the first argument, appended by the animation(s).
I made a games where different items(rectangles with textures) should be created regularly. These Items are always moving left (like this) so it should look like this:
But if it's lagging or if I click on the menu bar (where the close button etc. is)
and the game "pauses" the items aren't spawning regularly so it looks like this:
This is obstructing the gameplay so I want to fix this.
This is the part where I spawn the items:
public void renderMain(){
timeState += delta;
if (timeState >= 0.32f) {
timeState = 0f;
Item.spawnitem();
}
...
How do I fix this?
I recently bought the book Learn Cocos 2d 2, and have been following the tutorial on how to make my first game(chapter 4). Basically, what is supposed to happen in the game where I am in the book, you are the alien, and you have to tilt to avoid falling spiders. If you hit one, the game resets.
The probelem I'm having is that the collision detecting doesn't work. The spiders fall and pass through me, the game doesn't reset. As far as I can tell (I just started), it should work, and I couldn't find any differences between the book and this.
This is the code(It's actually an exaple of the game without collisions, and I added the code the book told me to)
http://pastebin.com/0Jt9PdMy
As far as I know(not much), it should work.
Any help?
I guess you would need to stop the spiders actions in that reset loop:
for (int i = 0; i < numSpiders; i++)
{
CCSprite* spider = [spiders objectAtIndex:i];
[spider stopAllActions]; // add this
spider.position = CGPointMake(imageSize.width * i + imageSize.width * 0.5f, screenSize.height + imageSize.height);
}
On request I have implemented support for moving an OS X window by dragging it using an area within the content part of the window, i.e replicating the drag and move functionality of the title bar but in another area.
The problem I have yet to resolve is the fact that if the user drags the mouse quickly it can leave the window area and then no more mouse move events are received.
On windows this type of problem can simply be fixed by calling the win32 method SetCapture(), what's the corresponding OSX method?
This application is a cross platform C++ application using Carbon for the OS X specific parts. (And yes, I know all about the Cocoa benefits but this is an older code base and there no time nor money for a Cocoa port at this point in time.)
I have found Carbon API methods like for example TrackMouseLocation() but can't really see how I could use them for this application. In listing 2-7 here http://developer.apple.com/legacy/mac/library/documentation/Carbon/Conceptual/Carbon_Event_Manager/Tasks/CarbonEventsTasks.html
the mouse is captured but the problem is that TrackMouseLocation() blocks waiting for input. Blocking is something this application can not do since it also host a flash player that must be called many times per second.
The protototype I have assembled when trying to figure this out basically looks like this:
switch(GetEventKind(inEvent))
{
case kEventMouseDown:
// A silly test to make parts of the window border "draggable"
dragging = local_loc.v < 25 || local_loc.h < 25;
last_screen_loc = screen_loc;
break;
case kEventMouseUp:
dragging = false;
break;
case kEventMouseMoved:
break;
case kEventMouseDragged:
if (dragging) {
Rect rect;
GetWindowBounds (windowRef, kWindowContentRgn, &rect);
int dx = screen_loc.h - last_screen_loc.h;
int dy = screen_loc.v - last_screen_loc.v;
rect.left += dx;
rect.right += dx;
rect.top += dy;
rect.bottom += dy;
SetWindowBounds (windowRef, kWindowContentRgn, &rect);
}
last_screen_loc = screen_loc;
break;
Any ideas appreciated?
I feel you should track mouse in Window as well as out of window. Following code should solve your problem,
EventHandlerRef m_ApplicationMouseDragEventHandlerRef;
EventHandlerRef m_MonitorMouseDragEventHandlerRef;
{
OSStatus ErrStatus;
static const EventTypeSpec kMouseDragEvents[] =
{
{ kEventClassMouse, kEventMouseDragged }
};
ErrStatus = InstallEventHandler(GetEventMonitorTarget(), NewEventHandlerUPP(MouseHasDragged), GetEventTypeCount(kMouseDragEvents), kMouseDragEvents, this, &m_MonitorMouseDragEventHandlerRef);
ErrStatus = InstallApplicationEventHandler(NewEventHandlerUPP(MouseHasDragged), GetEventTypeCount(kMouseDragEvents), kMouseDragEvents, this, &m_ApplicationMouseDragEventHandlerRef);
return true;
}
//implement these functions
OSStatus MouseHasDragged(EventHandlerCallRef inCaller, EventRef inEvent, void *pUserData){}
Hope it helps!!
I Hope It Help´s you too:
// Get Mouse Position --> WAY 1
printf("Get Mouse Position Way 1\n");
HICoordinateSpace space = 2;
HIGetMousePosition(space, NULL, &point);
printf("Mouse Position: %.2f %.2f \n", point.x, point.y);
// Get Mouse Position --> WAY 2
printf("Get Mouse Position Way 2\n");
CGEventRef ourEvent = CGEventCreate(NULL);
point = CGEventGetLocation(ourEvent);
printf("Mouse Position: %.2f, y = %.2f \n", (float)point.x, (float)point.y);
I´m looking for the way to get a WindowPart Reference at a certain location (over all windows of all aplications)
Certain methods in Carbon doesn´t work, always return 0 as a windowRef... Any ideas?
You could also try just calling DragWindow in response to a click in your window's content area. I don't think you need to implement the dragging yourself.