When I sue the following code the body graphic is removed, however in debug mode I can still see the outline of the body which would suggest the body still exists. How do I totally remove this body?
private function updateGraphics(b:Body) {
if (b.position.y > 360) {
play.removeChild(b.userData.graphic);
}
}
Nape has nothing to do with graphics. A Body is not magically tied to the way you display it on the screen, so removing a flash displayObject from a display list cannot possibly remove the nape body from the space.
The answer, is to remove it from the nape space!
body.space = null;
is the simplest way.
Related
I have a MFC Dialog based application. I have placed a Picture Control (of type Bitmap) to display an initial/default resource bitmap. That displays just fine when the app starts.
When a user selects an item in a CListbox, I want to change the bitmap resource displayed. A CStatic control variable m_Bitmap was created and I change it based on the users' listbox selection. Then I update the controls.
Upon execution, the original bitmap simply disappears and the control fails to display the new bitmap. I have used the same technique with static text control variables and CStrings and it works fine.
Why are my bitmaps failing to change? Tried calling the picture controls' RedrawWindow() function with a CWnd pointer which does nothing either.
This should be an easy thing to do in MFC...
//Code Snippet
//
//Picture Control (IDC_BitmapCntl), control variable is m_Bitmap
// DDX_Control(pDX, IDC_BitmapCntl, m_Bitmap);
//
//Code from CList Control, OnLbnSelchange() function, CListbox variable is m_Selection
//
switch (m_Selection) { //Select a coresponding bitmap to display
case (0):
m_Bitmap.SetBitmap((HBITMAP)IDB_Bitmap1);
break;
case (1):
m_Bitmap.SetBitmap((HBITMAP)IDB_Bitmap2);
break;
//additional cases ommited for brevity
default:
break;
}
UpdateData(FALSE); //this should update the control but does not display new bitmap
//Failed attempt to then redraw control
CWnd* pDlg;
pDlg = GetDlgItem(IDC_BitmapCntl);
pDlg->RedrawWindow(); //cannot access OnPaint() via a pointer
//end snippet
No errors on compilation. Initial bitmap image displays OK but disappears when user selects an item in listbox. New bitmap is not displayed.
Assuming that IDB_Bitmap1 and IDB_Bitmap2 are (integral) resource identifiers for the bitmaps you want (defined in an .rc or .rc2 file), then you can't just simply cast them with (HBITMAP)IDB_Bitamp1 (HBITMAP is actually a pointer, and it will then point to who-knows-what => the dreaded undefined behaviour).
You have to use the LoadBitmap() function (or something similar) to get the actual bitmap from the application's resources. The simplest way is using a (local) CBitmap object:
//...
CBitmap bitmap;
switch (m_Selection) { //Select a coresponding bitmap to display
case 0: // Don't really need brackets around case 'values'
bitmap.LoadBitmap(IDB_Bitmap1); // "LoadBitmap" will have "W" appended for Unicode builds
break; // or "A" appended for non-Unicode ('ASCII') builds.
case 1:
bitmap.LoadBitmap(IDB_Bitmap2); // Probably best practice to use the 'native' names?
break;
// Additional cases ...
default: // Strictly speaking, unnecessary, but I like to put this catch-all in ...
break; // ... and good for you, for also having it!
}
m_Bitmap.SetBitmap(bitmap.operator HBITMAP());
// Strict way to do it, but you can omit the ".operator HBITMAP()" in MOST cases.
Hope this helps!
PS: You really ought to do something (in the default case, maybe) to put a 'valid' bitmap in CBitmap for un-handled cases.
I'm trying to implement svg.js to make a map of a clickable floorplan.
But I cannot make this work properly, or this works but doesn't work like I expected:
const map = SVG.get('mysvg');
map.click(function( event ) {
this.fill({ color: '#000' });
console.log(this);
console.log(event.target);
});
When I try to click on some area on the map, instead of change fill color I get nothing.
Actually svgjs triggers 'create' as you can see in console with inspector.
Not sure what am I doing wrong here?
I would expect that the area will change fill color?
https://codepen.io/bobz-zg/pen/LdyXBe
You can use the select function as described here to create a Set. You'd then use the each() method from Set to iterate over each entry and apply the click event handler. For example:
const map = SVG.get("mysvg");
var restaurants = map.select('[id*="restaurant"]:not(g)'); // Create an svg.js Set, but do not capture the group in the set
restaurants.each(function() {
this.click(function(event) {
this.fill({ color: "#000" });
});
});
If you can edit the svg that you are using as an input, I would suggest adding a class to each of the clickable elements to use that as the reference for select. Otherwise, you'll have to do something like selecting all element id 'types' (i.e. restaurant, retail etc.) separately and concatenating the Sets using Set.add() before you do the loop to add the click listener, but that could get messy.
I want to be able to just place a View component (plugin) into the page through code and have it appear at some X\Y on the page... but I'm a bit stumped.
Any attempt to add via page.content kinda adds it to the layout\render pass so it occupies space.
So this would get injected into "any" page at "any" time, I have no control over the markup this would be used in (know what I mean?) There is no XML for it and unfortunately the answer can't just be wrap everything in an AbsoluteLayout because one can't mandate that on users apps\layouts.
Thoughts, even possible?
Basically the simplest way to do this is to dynamically and be fully cross platform compatible is to create a AbsoluteLayout item in your JavaScript code, and dynamically insert your item and the AL into the page container.
Code would be something like this:
var AbsoluteLayout = require('ui/layouts/absolute-layout').AbsoluteLayout;
var myAL = new AbsoluteLayout();
var myItem = new myPluginItem();
// Set you left, right, top, bottom coords.
myItem.top = x;
// Add our item to the AbsoluteItem
myAL.addChild(myItem);
var frame = require('ui/frame');
var page = frame.topmost().currentPage;
var LayoutBase = require('ui/layouts/layout-base').LayoutBase;
page._eachChildView(function(view) {
if (view instanceof LayoutBase) {
view.addChild(myAL);
return false;
}
return true;
});
However, if you don't want to do this the really simple way; the only other way is to actually go a bit lower level. You can natively access the iOS view controller (page._ios.view) and the android view (page._nativeView), and then manually add it to the view by using things like addView (https://developer.android.com/reference/android/view/ViewManager.html) or addSubview (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/).
I would like to add you can set the Top and Left properties in TypeScript by importing AbsoluteLayout like so
import {AbsoluteLayout} from 'ui/layouts/absolute-layout';
and then using the exposed functions setLeft or setTop
AbsoluteLayout.setLeft(YourItem, LeftValue);
or
AbsoluteLayout.setTop(YourItem, TopValue);
Just wondering if it is possible to have no animations in section when adding/removing elements in the section. Or even when adding/removing the section itself.
On ViewWillAppear I check a global boolean to see if the app has been exited/reopened. This will then cause it to reload new data. (Did have RefreshRequested set up, but the client wanted it this way). So on ViewWillAppear we call a function called UpdateCells which does the following.
// Using Bottom animation as its the closest to none (none has no fade effects
// but makes solid cells move upwards in the TableView and then suddenly disappear)
Root.Remove(mySection1, UITableViewRowAnimation.Bottom);
Root.Remove(mySection2, UITableViewRowAnimation.Bottom);
mySection1.Clear();
mySection2.Clear();
// Load stuff from SQLite DB and populate sections. Adding looks like:
// if (isThisWeek)
// {
// section1.Insert(0, UITableViewRowAnimation.None, newElement);
// }
// else
// {
// section2.Insert(0. UITableViewRowAnimation.None, newElement);
// }
// Now finally add sections back into Root if there exists elements in them.
if (sectionThisWeek.Count > 0)
{
Root.Insert(1, UITableViewRowAnimation.None, sectionThisWeek);
}
if (sectionCommingUp.Count > 0)
{
Root.Insert(1, UITableViewRowAnimation.None, sectionCommingUp);
}
I was hoping for some sort of, pause everything in the DialogViewController, work on it, then do a ReloadComplete() with no animations.. somehow...
Any ideas what I'm doing wrong, or a better way to do what I am trying to do.
If you are reloading all the data at once, you can just assign the entire new value to the Root property on the DialogViewController and no animations would be shown.
I am writing a Google extension. Here my content script modifies a page based on a list of keywords requested from background. But the new innerHTML does not show up on the screen. I've kluged it with an alert so I can see the keywords before deciding to actually send a message, but it is not how the routine should work. Here's the code:
// MESSAGE.JS //
//alert("Message Page");
var keyWordList= new Array();
var firstMessage="Hello!";
var contentMessage=document.getElementById("message");
contentMessage.value=firstMessage;
var msgComments=document.getElementsByClassName("comment");
msgComments[1].value="Hello Worlds!";//marker to see what happens
chrome.extension.sendRequest({cmd: "sendKeyWords"}, function(response) {
keyWordList=response.keyWordsFound;
//alert(keyWordList.length+" key words.");//did we get any keywords back?
var keyWords="";
for (var i = 0; i<keyWordList.length; ++i)
{
keyWords=keyWords+" "+keyWordList[i];
}
//alert (keyWords);//let's see what we got
document.getElementsByClassName("comment")[1].firstChild.innerHTML=keyWords;
alert (document.getElementsByClassName("comment")[1].firstChild.innerHTML);// this is a band aid - keyWords does not show up in tab
});
document.onclick= function(event) {
//only one button to click in page
document.onload=self.close();
};
What do I have to do so that the text area that is modified actually appears in the tab?
(Answering my own question) This problem really has two parts. The simplest part is that I was trying to modify a text node by setting its value like this:
msgComments1.value="Hello Worlds!"; //marker to see what happens
To make it work, simply set the innerHTML to a string value like this:
msgComment1.innerHTML="Hello Worlds!"; //now it works.
The second part of the problem is that the asynchronous call to chrome.extension.sendRequest requires a callback to update the innerHTML when the reply is received. I posted a question in this regard earlier and have answered it myself after finding a solution in an previous post by #serg.