Hide a view in Titanium so that it does not take physical space - titanium

In titanium it is possible to hide a view like so:
$.foo.hide()
or
$.foo.visible = false
However, in both cases the object still seems to take physical space. It is just invisible. In other words it is similar to the CSS property visibility: hidden.
I want it so that it disappears and take no physical space in terms of width or height, so it's similar to the CSS property display: none
How can I do this?
The best hacky solution I have is the following:
$.foo.width = 0;
$.foo.height = 0;
$.foo.left = 0;
$.foo.right = 0;
But that means when I want to make it visible again, I have to set all those properties back to their original values which is a pain and hard to maintain.

First of all, don't afraid of doing some hard coding ;)
Coming to your query, yes, this is true that hiding a view just hide it from UI, but physical-space is still there.
To do what you want, you will need to either remove view on hide & create it on show, or you can use absolute layout in some tricky way.
Other way could be to animate this view using transform property like this:
// on hide
$.foo.animate({
duration : 100,
transform : Ti.UI.create2DMatrix({scale:0})
}, function () {
$.foo.visible = false;
});
// on show
$.foo.visible = true; // we need to make it visible again before resetting its UI state since we hid it after completion of animation in above code
$.foo.animate({
duration : 100,
transform : Ti.UI.create2DMatrix() // passing empty matrix will reset the initial state of this view
});
OR
this could also work but never tried this:
// on hide
$.foo.transform = Ti.UI.create2DMatrix({scale:0});
$.foo.visible = false;
// on show
$.foo.visible = true;
$.foo.transform = Ti.UI.create2DMatrix();

Related

Custom CollapsingTopAppBar Jetpack Compose

The essence of the problem is that I want to write my own version of the AppBar that would include content as another Compose function. After looking at the source code of the current CollapsingTopAppBar implementation, I saw the following lines:
#Composable
private fun TwoRowsTopAppBar(
...
scrollBehavior: TopAppBarScrollBehavior?
) {
...
val pinnedHeightPx: Float = 64.dp
val maxHeightPx: Float = 152.dp
LocalDensity.current.run {
pinnedHeightPx = pinnedHeight.toPx()
maxHeightPx = maxHeight.toPx()
}
// Sets the app bar's height offset limit to hide just the bottom title area and keep top title
// visible when collapsed.
SideEffect {
if (scrollBehavior?.state?.heightOffsetLimit != pinnedHeightPx - maxHeightPx) {
scrollBehavior?.state?.heightOffsetLimit = pinnedHeightPx - maxHeightPx
}
}
...
Surface(...) {
Column {
TopAppBarLayout(
...
heightPx = pinnedHeightPx
...
)
TopAppBarLayout(
...
heightPx = maxHeightPx - pinnedHeightPx + (scrollBehavior?.state?.heightOffset
?: 0f),
...
)
}
}
}
As I understand it, scrollBehavior is used to handle the collapse and expansion behavior. In the current implementation, just constant values are put in heightOffsetLimit. And since I need my appbar implementation to be able to contain content of any size, I need to somehow know the size of this content in advance and put this value in heightOffsetLimit.
I have already written the code for my AppBar, so that it also contains content. But since I can't pass the height value of the content to scrollBehavior, the AppBar doesn't collapse to the end.
you need to calculate the height that the appbar will have before drawing it into the screen. I have followed this issue and solved my problem with the last solution. hope it helps:
Get height of element Jetpack Compose
use the content you can put (ex. an image or a huge text) as the MainContent
use your appbar as the DependentContent and use the size given in lambda to give the height to your appbar
finally set placeMainContent false as I believe you don't need to draw the image (or any other composable) directly in a box
and you will good to go

how to turn lock aspect ratio on/off programatically

codesandbox
As you can see in the sandbox, lock-aspect-ratio property works as expected. However, I'd like to change width/height programmatically with a different aspect ratio from the original one and then make lock-aspect-ratio active again. Any possible ways to do this? I wanna stick with the same lock-aspect-ratio when it comes to resizing.
setSize: function () {
# something like this.$refs.vueDraggableResizeable.lockAspectRatio = false
this.w = 300;
this.h = 100;
# something like this.$refs.vueDraggableResizeable.lockAspectRatio = true
}

Famo.us/Angular Sticky Background Position ScrollView Sync

I'm trying to create functionality very similar to most websites these days.
The concept is 3 sections the size of the browser, the background images are supposed to be fixed positioned and revealed by the div scrolling up and down.
We need this to function as beautifully on mobile as it does on desktop, and it looks like Famous/angular is the solution.
Here is a pen.
http://codepen.io/LAzzam2/pen/XJrwbo
I'm using famous' Scroll.sync, firing javascript that positions the background image on every start / update / end.
scrollObject.sync.on("update", function (event) {
console.log('update');
test(event);
});
here is the function positioning the backgrounds.
function test(data){
var scroller = document.getElementsByClassName('famous-group');
styles = window.getComputedStyle(scroller[0], null);
tr = styles.getPropertyValue("-webkit-transform").replace('matrix(1, 0, 0, 1, 0,','').replace(')','');
var distanceTop = -(parseInt(tr));
var sections = document.getElementsByClassName('section');
sections[3].style.backgroundPosition="50% "+distanceTop+"px";
sections[4].style.backgroundPosition="50% "+(-(window.innerHeight)+distanceTop)+"px";
sections[5].style.backgroundPosition="50% "+(-(window.innerHeight*2)+distanceTop)+"px";
};
Any input / suggestions / advice would be wonderful, really just looking for a proof of concept with these 3 background images scrolling nicely.
That jittery-ness is unfortunate, I can't tell what would be causing the issue, except maybe the order in which events are fired?
**There are known issues, only works in -webkit browsers as of now
I think your idea to use Famous is good, but probably what I would do, would be taking a different approach to the problem.
You are solving this by touching the DOM, that is exactly what both Angular and Famous are meant to avoid.
If I had to face the same goal, I would probably use a Famous surface for the background instead of changing the property of the main one and synchronize its position with the scrolling view.
So, in your code, it would be something like this:
function test(data){
var scrollViewPosition = scrollObject.getAbsolutePosition();
var newBackgroundPosition = // Calculate the new background position
var newForegroundPosition = // Calculate the new foreground position
var backgroundSurface = backgroundSurface.position.set(newBackgroundPosition);
var foregroundSurface = foregroundSurface.position.set(newForegroundPosition);
};

Thumbnail of previous image instead of cancel button while camera is open

i want to show the thumbnail of the previous image taken by camera instead of the cancel button while camera is running ...
Is that possible ?? Need help ..
Yep. Just capture the last image, keep it in memory (or save it to disk), then use it as one of the controls. We can do this using the overlay property of the Titanium.Media.showCamera function. Here is a quick example:
First we need an overlay view to show the image.
var overlayView = Ti.UI.createView();
var imageView = Ti.UI.createImageView({
width:44,
height:44,
left : 5
});
overlayView.add(imageView);
Now this is the function we use to open the camera with the overlay view. Note that we don't have controls so you need to add those (for closing etc). All we do right now is set the overlays image.
Titanium.Media.showCamera({
success:function(event) {
// called when media returned from the camera
imageView.image = event.media;
},
cancel:function() {},
error:function(error) {},
saveToPhotoGallery:true,
allowEditing:true,
mediaTypes:[Ti.Media.MEDIA_TYPE_PHOTO],
overlay : overlayView,
showControls: false // This is important!
});
To really make this work, you may need to save the event.media in a global variable, or use a similiar technique make sure overlayView will not be nulled out / garbage collected.
Also this is a barebones solution, not very robust, but this is the basic method I would use!

dojo splitter not resizing properly with dynamic content

I'm creating a seemingly simple dojo 1.8 web page which contains an app layout div containing a tab container and an alarm panel below the tab container. They are separated by a splitter so the user can select how much of the alarms or the tabcontainer they want to see.
Here's the example on jsfiddle:
http://jsfiddle.net/bfW7u/
For the purpose of the demo, there's a timer which grows the table in the alarm panel by an entry every 2 seconds.
The problem(s):
If one doesn't do anything and just lets the table grow, no scroll bar appears in the alarm panel.
If one moves the splitter without having resized the browser window first, the splitter handle ends up in a weird location.
Resizing the browser window makes it behave like I would expect it to begin with.
Questions:
Am I doing something wrong in the way I'm setting things up and that's causing this problem?
How can I catch the splitter has been moved event (name?)
How do I resize the splitter pane to an arbitrary height? I've tried using domStyle.set("alarmPanel", "height", 300) and this indeed sets the height property... but the pane does not resize!
Any help greatly appreciated!
I forked your jsFiddle and made some modifications to it: http://jsfiddle.net/phusick/f7qL6/
Get rid of overflow: hidden in html, body and explicitly set height of alarmPanel:
.claro .demoLayout .edgePanel {
height: 150px;
}
This tricky one. You have two options: to listen to splitter's drag and drop or to listen to ContentPane.resize method invocation. Both via dojo/aspect:
// Drag and Drop
var splitter = registry.byId("appLayout").getSplitter("bottom");
var moveHandle = null;
aspect.after(splitter, "_startDrag", function() {
moveHandle = aspect.after(splitter.domNode, "onmousemove", function() {
var coords = {
x: !splitter.horizontal ? splitter.domNode.style.left : 0,
y: splitter.horizontal ? splitter.domNode.style.top : 0
}
dom.byId("dndOutput").textContent = JSON.stringify(coords);
})
});
aspect.after(splitter, "_stopDrag", function() {
moveHandle && moveHandle.remove();
});
// ContentPane.resize()
aspect.after(registry.byId("alarmPanel"), "resize", function(duno, size) {
dom.byId("resizeOutput").textContent = JSON.stringify(size);
});
Call layout() method after changing the size:
registry.byId("alarmPanel").domNode.style.height = "200px";
registry.byId("appLayout").layout();