I'm currently working on a file-manager with vala and clutter and i was wondering is it possible to display GLib.Icon ( Fileinfo.get_icon() ) in Clutter.Image instead of just displaying one folder icon from it's location?
If the icon is a GLib.LoadableIcon you should be able to use GLib.LoadableIcon.load to get a GLib.InputStream, then us that to create a Gdk.Pixbuf with Gdk.Pixbuf.from_stream. From there use Clutter.Image.set_data to copy the data into the Clutter.Image.
To test whether the icon is a GLib.LoadableIcon, just do something like GLib.LoadableIcon loadable_icon = icon as GLib.LoadableIcon; if (loadable_icon != null) { ... }
Related
I know that it is not the best title in the world but let me explain the problem first,
I have implemented a Glance widget with some items in it and when you press them, the app should be opened and navigated to the specific screen given via deep-link in NavHost. However, sometimes the page navigated via deep-link works and sometimes not. When it is not, got an error something like this:
Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4d in tid 2486 (DefaultDispatch), pid 2259
I believe this is a segmentation error as I pass the argument from widget to app by using Gson()toJson(itemData). However, I do not understand why this sometimes works as I use the same thing for each item in order to open the app and navigate to the details screen.
The other thing is when the app does not crash with that error, the app directly opens the details page rather than showing the splash screen first and navigating to the detail screen.
In the end, how can I solve that segmentation error during deep-linking and how can I prepopulate the backstack(or just first navigate to splash and then to detail screen)?
For some more information, there is a sample code:
// CODE IN GLANCE WIDGET
#Composable
private fun Item(
model: ItemData,
) {
val intent = Intent(
Intent.ACTION_VIEW,
"${URL}/${Screens.DetailScreen.passArgument(model.toDetailData())}".toUri() // pass model just converts detailData to string with Gson().toJson()
)
Text(
text = model.title ?: "",
modifier = GlanceModifier
.clickable(
actionStartActivity(
intent
)
)
)
}
// CODE IN NAVHOST
NavHost(
// navhost parameters such as route, controller, start destination
// where start destination set to Splash Screen
){
composable(/*routeOfSpashScreen*/){SplashScreen}
.
. // These dots are some sub-navGraphs
.
.
detailScreenNavGraph()
}
// DETAIL SCREEN SUB-NAVGRAPH
fun NavGraphBuilder.detailScreenNavGraph(
controller: NavHostController? = null // This is optional and does not relate to problem
) {
navigation(
startDestination = Screens.DetailScreen.route,
route = DETAIL_SCREEN_ROUTE
) {
composable(
route = Screens.DetailScreen.route + "/{model}",
arguments = listOf(
navArgument(
name = "model"
) {
type = DetailDataNavType()
},
),
deepLinks = listOf(
navDeepLink {
uriPattern = "${URL}/" + Screens.DetailScreen.route + "/{model}"
}
)
) {
val model = it.arguments?.getParcelable<DetailData>("model")
if (model != null) {
DetailScreen(
model,
controller = controller ?: LocalNavigationManager.current
)
}
}
}
}
Any help or advice is appreciated.
Since no one is answering and I have solved my problem, I believe a proper explanation is needed if someone gets stuck like me.
What are receivers and how do they work?
Receivers are like singleton classes that control each widget, not only the widget called by. If you have to update the widget, you should have its proper GlanceId; currently, there is no official way to get that id. However, there is a hacky way such as:
// Add this to your callback and to your intent before broadcasting it
// so you can access the widget's GlanceId
val id = glanceId.toString().filter { it.isDigit() }.toInt()
Since you have the id in your onReceive of your receiver, you can properly update your widget
Why I am having a "Cannot marshall a parcel that contains binder objects" error?
This is because you are using LazyRow or LazyColumn and during drawing, as bitmaps contain smart components named binders which take extra space in your memory during drawing, you exceed the available limit given to the widget for memory. I have tried to reduce the size of the image and compress it as much as possible and it loads with the most disgusting images. However, if you use a Column instead of LazyColumn' you can easily render any image, at least this is what I have experienced.
How are these questions relate to my problem?
As I was trying to click an item on the widget that lazily loaded, I believe that I tried to access a memory space that has been either collected or freed during or after the widget is drawn. The other possibility is there was no memory space for the app to be launched and during launch, the memory is cleaned and I tried to access the deleted memory part. Either way, these are just assumptions and feel free to correct me if I am wrong.
What about the backstack part?
I totally changed the deeplink handling mechanism of the app such as:
if(appIsClosed)
start splash -> navigate home -> open the desired page from here
// pass the received intent parameters throughout navigation hierarchy
else
handle as deep-link to home -> open desired page from here
How do I add a clickable link to any of the image slices so the user can click a slice to go to a url? Currently they can spin the wheel to get a random url choice. I got the random spin part working using “IF” but I got stuck figuring out the image slice click idea.
I'm currently working at the top of page in an area called:
//add code here?
if (clickedSegment) {
clickedSegment.indicatedSegment = "Jane";
window.location = "https://www.mikeloucas.com";
theWheel.draw();
and I have one url working due to the "clickedSegment" but it's active on all the slices and not what I need (I'm try to target Jane) so I'll keep at it unless some has an answer.
Separately but related:
This is one of the image segments I'm trying to add add link to:
{'image' : 'https://mikeloucas.com/wheel/jane.png', 'text' : 'Jane'},
The original tutorial shows how to change the colour of a slice on click, but I’d like to go to a url instead.
Original Click Code: http://dougtesting.net/winwheel/docs/tut15_get_segment_clicked
The thing Im working on: https://codepen.io/mikeloucas/pen/qBarWoP
In my Codepen example I turned off the “IF” load url because its just in the way when testing, but feel free to turn it on see it in action. It’s WAY down the page lol; you’ll see:
if (indicatedSegment.text == "Jane") {
window.location = "https://www.mikeloucas.com";
WAS:
let clickedSegment= theWheel.getSegmentAt(e.clientX, e.clientY);
if (clickedSegment) {
clickedSegment.indicatedSegment = "Jane";
window.location = "https://www.mikeloucas.com";
theWheel.draw();
IS NOW:
let segmentImage = theWheel.getSegmentAt(e.clientX, e.clientY);
if (segmentImage.text == "Jane") {
window.location = "https://www.mikeloucas.com";}
else if (segmentImage.text == "othername")...{
}
...theWheel.draw();
The trick (for me) was changing "clickedSegment" to "segmentImage" because "segmentImage" was already calling the array of names. I also add an "ELSE IF" because I had lots of slices to work work with.
See working thingy here: https://codepen.io/mikeloucas/pen/qBarWoP
My version needs to have the URL and NAME LIST entered twice; it would be cool if someone knows how to do it once (one set instead of two) but maintain both functions of the "CLICK url" and "SPIN url", so I'm still open to advice.
I'd prefer one set over two. :-)
I am learning about fluid dynamics (and Haxe) and have come across this awesome project and thought I would try to extend to it to help me learn. A demo of the original project in action can be seen here.
So far, I have created a side menu of items containing different shapes. When the user clicks on one of the shapes, then, clicks onto the canvas, the image selected should be imprinted onto the dye. The user will then move the mouse and explore the art etc.
To try and achieve this I did the following:
import js.html.webgl.RenderingContext;
function imageSelection(): Void{
document.querySelector('.myscrollbar1').addEventListener('click', function() {
// twilight image clicked
closeNav();
reset();
var image:js.html.ImageElement = cast document.querySelector('img[src="images/twilight.jpg"]');
gl.current_context.texSubImage2D(cast fluid.dyeRenderTarget.writeToTexture, 0, Math.round(mouse.x), Math.round(mouse.y), RenderingContext.RGB, RenderingContext.UNSIGNED_BYTE, image);
TWILIGHT = true;
});
After this call, inside the update function, I have the following:
override function update( dt:Float ){
time = haxe.Timer.stamp() - initTime;
performanceMonitor.recordFrameTime(dt);
//Smaller number creates a bigger ripple, was 0.016
dt = 0.090;//#!
//Physics
//interaction
updateDyeShader.isMouseDown.set(isMouseDown && lastMousePointKnown);
mouseForceShader.isMouseDown.set(isMouseDown && lastMousePointKnown);
//step physics
fluid.step(dt);
particles.flowVelocityField = fluid.velocityRenderTarget.readFromTexture;
if(renderParticlesEnabled){
particles.step(dt);
}
//Below handles the cycling of colours once the mouse is moved and then the image should be disrupted into the set dye colours.
}
However, although the project builds, I can't seem to get the image imprinted onto the canvas. I have checked the console log and I can see the following error:
WebGL: INVALID_ENUM: texSubImage2D: invalid texture target
Is it safe to assume that my cast for the first param is not allowed?
I have read that the texture target is the first parameter and INVALID_ENUM in particular means that one of the gl.XXX parameters are just flat out wrong for that particular function.
Looking through to the file writeToTexture is declared as so: public var writeToTexture (default, null):GLTexture;. WriteToTexture is a wrapper around a regular webgl handle.
I am using Haxe version 3.2.1 and using Snow to build the project. WriteToTexture is defined inside HaxeToolkit\haxe\lib\gltoolbox\git\gltoolbox\render
writeToTexture in gltoolbox is a GLTexture. With snow and snow_web, this is defined in snow.modules.opengl.GL as:
typedef GLTexture = js.html.webgl.Texture;
So we're simply dealing with a js.html.webgl.Texture here, or WebGLTexture in native JS.
Which means that yes, this is definitely not a valid value for texSubImage2D()'s target, which is specified to take one of the gl.TEXTURE_* constants.
A GLenum specifying the binding point (target) of the active texture.
From this description it's obvious that the parameter isn't actually for the texture itself - it merely gives some info on how the active texture should be used.
The question then becomes how the "active" texture can be set. bindTexture() can be used for this.
When editing a vertex I would like to substitute the vertex symbol with SimpleMarkerSymbol and a TextSymbol but that appears to be impossible. Any suggestions on how I could do this? I want the appearance of dragging something like this (text + circle):
After taking some time to look at the API I've come to the conclusion it is impossible. Here is my workaround:
editor.on("vertex-move", args => {
let map = this.options.map;
let g = <Graphic>args.vertexinfo.graphic;
let startPoint = <Point>g.geometry;
let tx = args.transform;
let endPoint = map.toMap(map.toScreen(startPoint).offset(tx.dx, tx.dy));
// draw a 'cursor' as a hack to render text over the active vertex
if (!cursor) {
cursor = new Graphic(endPoint, new TextSymbol({text: "foo"}));
this.layer.add(cursor);
} else {
cursor.setGeometry(endPoint);
cursor.draw();
}
})
You could use a TextSymbol to create a point with font type having numbers inside the circle. Here is one place where you can find such font. http://www.fontspace.com/the-fontsite/combinumerals
Wont be exactly as shown in the image but close enough. Also some limitation it wont work with IE9 or lower (this is as per esri documentation, as I am using halo to get the white border).
Here is the working Jsbin : http://jsbin.com/hayirebiga/edit?html,output use point of multipoint
PS: I have converted the ttf to otf and then added the font as base64, which is optional. I did it as I could not add the ttf or otf to jsbin.
Well, Achieve this seems impossible so far however ArcGIS JS API provides a new Application/platform where you can generate single symbol online for your applications.
We can simply create all kind of symbols(Provide by ESRI) online and it gives you on the fly code which you just need to paste in your application.
This will help us to try different type of suitable symbols for the applications.
Application URL: https://developers.arcgis.com/javascript/3/samples/playground/index.html
Hoping this will help you :)
i have two volumes (.nrrd) of different qualities. the user can browse through the layers. if a key is pressed
i want to load the slice of the volume with better quality.
my volume is similar to this one: lesson 10 xtk
i've found:
volume.children[2].children[0].children[0].texture.file = "http://path/to/file.ext";
but if i apply some kind of file (.jpg, .dcm) nothing happens.
is this the right approach to change the slice to go inside the children and change the texture?
or shall i load the selected slice seperate as an object and apply it to the "lower-quality-volume" somehow?
edit:
this is what i tried so far (i get errors with dcms but not with jpgs):
if (event.keyCode == 83) { // "s"-button
volume.children[2].children[0].children[0].texture.file = "http://localhost:3000/112.jpg";
volume.children[2].children[0].children[0].modified();
r.render();
}
edit2: this is whats in my r.onShowtime = function() {}
volume.children[2].children[0].texture.file = 'http://localhost:3000/112.jpg';
volume.children[2].children[0].visible = true; // to activate the first layer
volume.children[2].children[0].modified();
console.log(volume.children[2].children[0].visible +" "+ volume.children[2].children[0].texture.file);
it outputs "true hostname/112.jpg"
when i inspect the .jpg in firebug the header is ok but the answer is "null"
when i inspect console.log(volume.children[2].children[0]); with firebug
.texture.file is set to hostname/112.jpg
when i go to "network" the .jpg has been transfered successfully
please notice that 112.jpg and level.jpg are the same. the first one is getting loaded in r.onShowtime and the other one is loaded at a keypressed event.
EDIT 3: volume.children[2].children[0] is of the type "X.slice", isn't it?
here is my approach: jsFiddle
and this is my actual issue and still not working: jsFiddle
Mhh..
I think a call to object.modified() is missing in the file setter (and in others setters from inject classes). Let's see when Haehn will come if he wants to change something internaly, but for the moment could you try to call it by yourself ?
You can try to add after the modification of texture :
volume.children[2].children[0].children[0].modified();
And if it doesn't work, in addition :
renderer.render();
Edit :
It's strange, I did a similar code and it did something. Can you please try something like that with opening your javascript console (Firefox, Chrome,... has one) and tell me the error you get ?
renderer.onShowtime = {
for (var i=0 ; i< volume.children[2].children.length ; i++) {
volume.children[2].children[i].texture.file="myimage.jpeg";
volume.children[2].children[i].modified();
}
}
It is important you call it in the onShowtime, because before the volume is not loaded, and so slicesX, slicesY... don't exist.
Edit2 :
Hey,
Thanks to the informations you added I think I've got the point ! In the render() method of our renderer3D there is a test on texture._dirty flag, that you cannot change from outside the framework. In addition the 1st rendering with a texture make that flag false, and loading a new texture doesn't seem to set that flag back to true in the current XTK. So, I think, we have to add it in the loader.load(texture, object) method. I'll make an issue on Github and see what Haehn thinks of it !