Image won't show when wrapped in stackpane (tornadoFX) - kotlin

I'm trying to create a field of grass and some cows on it.
Using a list of ones and zeros to decide which boxes are supposed to have a cow on it. And then I use flowpane to create my grid. When I try to add the image of a cow to a stackpane it doesn't show.
here is the relevant code:
override val root = flowpane {
this.setPrefSize(viewWidth * tileSize, viewHeight * tileSize)
//imageview("/cow.jpg")
for (i in hage) {
stackpane {
rectangle {
fill = GREEN
width = tileSize
height = tileSize
arcWidth = 5.0
arcHeight = 5.0
if (i == 1) {
/*circle {
fill = RED
radius = 10.0
}*/
imageview("/cow.jpg")
}
}
}
}
}
The out-commented image before the loop/stackpane shows (if it's not out-commented) and the stackpane works how I want it to if cows are represented as circles.
So how come the image isn't showing?

You're adding your ImageView to the Rectangle, not the StackPane. The Rectangle is a shape that doesn't render/support children. Try moving it outside of the rectangle {} block :)

Related

Highlighted marker window cut off at the left corner of Chart MPAndroidChart

I'm using a custom class for creating an MPAndroidChart marker. It's just a simple class where I'm using my own XML layout for creating a marker. I'm sending 35 entries to my chart and it's not scrollable. The problem is: if the highlight value at the beginning of the chart it's ok and marker window always sticks to left corner of the chart. But if highlight value is last then the highlighted marker gets cut off because of it's layout outside of chart. Why doesn't this behave same as left corner?
Now I'm drawing my marker always on top and at circle like this:
override fun getOffset(): MPPointF {
return MPPointF(-(width / 2).toFloat(), -lineChart.height.toFloat())
}
override fun getOffsetForDrawingAtPoint(posX: Float, posY: Float): MPPointF {
if (posX > chartView.width - width) {
offset.x = (-width).toFloat()
} else {
offset.x = (-(width / 2)).toFloat()
}
offset.y = -(height / 2).toFloat()
return offset
}
You need to set chart view to MarkerView.chartView before calculation.

UIImageView is not scrolling inside a scrollView

I am creating a scrollview with a page control. I have a scrollview added to my viewcontroller and inside the scrollview there is a UIImageView. But for some reason I cannot scroll it to the left or right side. Can anyone help me out to fix this problem?
My Code:
var tutorialImages: [String] = ["1", "2", "3"]
var frame = CGRect.zero
func pageControll() {
pageControllTutorial.numberOfPages = tutorialImages.count
for i in 0..<tutorialImages.count {
imageViewTutorial.frame = frame
imageViewTutorial.image = UIImage(named: tutorialImages[i])
scrollViewTutorial.addSubview(imageViewTutorial)
}
scrollViewTutorial.contentSize = CGSize(width: imageViewTutorial.frame.size.width * CGFloat(tutorialImages.count), height: imageViewTutorial.frame.size.height)
scrollViewTutorial.delegate = self
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
var pageNumber = scrollView.contentOffset.x / scrollView.frame.size.width
pageControllTutorial.currentPage = Int(pageNumber)
}
With the little bit of code you've shown, you're doing a number of things wrong.
Based on this line:
imageViewTutorial.image = UIImage(named: tutorialImages[I])
it looks like you have one UIImageView and you are setting its .image property 3 times, instead of creating 3 different image views.
Also, there is nothing in your code indicating how you are setting the frames of the image views.
I highly recommend using auto-layout instead of explicit frames - makes things much, much easier going forward.
Here is a complete example. It will create a square (1:1 ratio) scroll view 20-pts from the top with 20-pts padding on each side, and a UIPageControl below. It then adds a horizontal UIStackView to the scroll view. That stack view will hold the image views. Once the image views are added, the stack view will automatically define the "scrollable area" -- no need for calculating .contentSize.
Here's what it will look like:
Everything is done in code, so just assign the class of an empty view controller to SlidesExampleViewController ... no #IBOutlet or #IBAction connections needed.
class SlidesExampleViewController: UIViewController, UIScrollViewDelegate {
lazy var pageControl: UIPageControl = {
let v = UIPageControl()
v.backgroundColor = .brown
return v
}()
lazy var scrollView: UIScrollView = {
let v = UIScrollView(frame: .zero)
v.backgroundColor = .yellow
v.delegate = self
return v
}()
lazy var stackView: UIStackView = {
let v = UIStackView()
v.axis = .horizontal
v.alignment = .fill
v.distribution = .fill
v.spacing = 0
return v
}()
let tutorialImages: [String] = ["1", "2", "3"]
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
scrollView.translatesAutoresizingMaskIntoConstraints = false
stackView.translatesAutoresizingMaskIntoConstraints = false
pageControl.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(scrollView)
view.addSubview(pageControl)
scrollView.addSubview(stackView)
let v = view.safeAreaLayoutGuide
let g = scrollView.contentLayoutGuide
NSLayoutConstraint.activate([
// constrain scroll view to top, leading, trailing with 20-pts "padding"
scrollView.topAnchor.constraint(equalTo: v.topAnchor, constant: 20.0),
scrollView.leadingAnchor.constraint(equalTo: v.leadingAnchor, constant: 20.0),
scrollView.trailingAnchor.constraint(equalTo: v.trailingAnchor, constant: -20.0),
// constrain scroll view height equal to scroll view width
scrollView.heightAnchor.constraint(equalTo: scrollView.widthAnchor),
// constrain stack view to all 4 sides of scroll view's contentLayoutGuide
stackView.topAnchor.constraint(equalTo: g.topAnchor),
stackView.bottomAnchor.constraint(equalTo: g.bottomAnchor),
stackView.leadingAnchor.constraint(equalTo: g.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: g.trailingAnchor),
// constrain stack view height equal to scroll view height
stackView.heightAnchor.constraint(equalTo: scrollView.heightAnchor),
// constrain page control width to 80% of scroll view width
pageControl.widthAnchor.constraint(equalTo: scrollView.widthAnchor, multiplier: 0.8),
// constrain page control top to 8-pts below scroll view bottom
pageControl.topAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 8.0),
// constrain page control centerX to centerX of scroll view
pageControl.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor, constant: 0.0),
])
tutorialImages.forEach { name in
if let img = UIImage(named: name) {
let imgView = UIImageView(image: img)
stackView.addArrangedSubview(imgView)
imgView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
}
}
pageControl.numberOfPages = tutorialImages.count
scrollView.isPagingEnabled = true
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageIndex = round(scrollView.contentOffset.x/view.frame.width)
pageControl.currentPage = Int(pageIndex)
}
}
Increase the contentSize of scroll view As (number of images * width of image) expecting all image are equal in size.
int startPosition = 0;
set the image origin.x
1 image1.frame.origin.x = startPosition;
startPosition = startPosition + image1.frame.size.width;
2 image2.frame.origin.x = startPosition;
startPosition = startPosition + image2.frame.size.width;
3 image3.frame.origin.x = startPosition;
startPosition = startPosition + image3.frame.size.width;
or either you can put these in a for loop to set the frame size of image.
The frame of each UIImageView is being set to CGRect.zero so they all have a 0 height and width, which means your scroll views contentSize is also 0x0. As far as the scroll view is concerned, there's nothing to scroll here.
Do this instead:
let image = UIImage(named: tutorialImages[i])
imageViewTutorial.frame = CGRect(x: widthSoFar, y: 0, width: image.width, height: image.height)
imageViewTutorial.image = image
scrollViewTutorial.addSubview(imageViewTutorial)
widthSoFar += image.size.width
Initialize widthSoFar outside the for loop to 0.
Always Keep the
Scroll view size is greater or equal to Imageview size.
check and keep UIImageView userInteraction Enable.
keep scroll view Content size as big as your number of image like for four
image in scoll view then (imageview.frame.size.width*4)
Content size = CGSize(imageview.frame.size.width*4,imageview.frame.size.height).

ImageView is not respecting the size of the CardView

I am trying to make some sort of gallery app. I would like to display images inside of a ScrollView inside a GridLayout so I used CardView for this and it looks like this:
But when I put ImageView inside each CardView, the CardView spreads and fills the whole ScrollView. Here's a preview:
The CardView is created programatically. Here's the code
fun CreateCardView(ItemCount: Int){
for (i in 1 until ItemCount){
/////////////////////CARD VIEW//////////////////////////////
val card_view = CardView(this)
card_view.radius = 8F
card_view.setContentPadding(8,8,8,8)
card_view.setCardBackgroundColor(Color.LTGRAY)
card_view.cardElevation = 8F
val param = GridLayout.LayoutParams()
param.rowSpec = GridLayout.spec(GridLayout.UNDEFINED, 1f)
param.columnSpec = GridLayout.spec(GridLayout.UNDEFINED, 1f)
card_view.layoutParams = param
val param2 = card_view.layoutParams as GridLayout.LayoutParams
param2.setMargins(10,10,10,10)
card_view.layoutParams = param2
subLayoutGrid?.addView(card_view)
////////////////////////END//////////////////////////////////////
///////////////////////IMAGEVIEW////////////////////////////////
val img = ImageView(this)
val imageparams = WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT
)
img.layoutParams = imageparams
img.scaleType = ImageView.ScaleType.CENTER_CROP
img.setImageResource(R.drawable.animaleight)
card_view.addView(img)
////////////////////////END///////////////////////////
}
}
How can I put ImageView inside the CardView without filling the whole ScrollView?
I've already fixed my problem. I've tried to use a 40px x 40px Picture then it worked the way I want to. See the image:
It seems like when you use high resolution Picture, the app cant handle the populating of ImageView in GridLayout.

UWP MapControl issue anchoring xaml children

I'm new to UWP MapControl currently. I have a simple problem when adding XAML children to map (instead of the regular map elements).
this is my code:
private void MapRightTapped(MapControl sender, MapRightTappedEventArgs args)
{
Ellipse circle = new Ellipse() { Height = 20, Width = 20, Fill = new SolidColorBrush(Colors.Black)};
sender.Children.Add(circle);
Geopoint position = new Geopoint(new BasicGeoposition()
{
Latitude = args.Location.Position.Latitude,
Longitude = args.Location.Position.Longitude,
Altitude = 5000,
});
MapControl.SetLocation(circle, position);
MapControl.SetNormalizedAnchorPoint(circle, new Point(0.5, 0.5));
}
At first the point displayed correctly on the map.
but after zooming or tilting the map,
the circle appeared to be anchored at the surface altitude and NOT at altitude of 5000
You need to set an altitude reference system. Leaving it set to the default of unspecified will cause the altitude value to be ignored.

Image Alignment when using resizeMode = contain

I'm using React Native's Image tag to display an image with a variable width and height. I have set the Image to 100x50 and set the resizeMode = contain which works almost perfectly, however if the image is resized, it's coming out completely centered vertically and horizontally. Can this behavior be altered? Mockup screenshot :
The red box indicates the Image element set at 100x50. The laptop pic represents the variable width/height picture. You'll notice that the behavior is pushing everything centered either vertically or horizontally.
In the second example, I would like the picture that takes up 100% of the height and roughly half the width to be pushed to be left aligned. Is this possible?
Thanks!
All - to possibly save some time in the future, this is a quick and dirty method I came up with to resolve this :
logoSize(width, height) {
var maxWidth = 110;
var maxHeight = 30;
if (width >= height) {
var ratio = maxWidth / width;
var h = Math.ceil(ratio * height);
if (h > maxHeight) {
// Too tall, resize
var ratio = maxHeight / height;
var w = Math.ceil(ratio * width);
var ret = {
'width': w,
'height': maxHeight
};
} else {
var ret = {
'width': maxWidth,
'height': h
};
}
} else {
var ratio = maxHeight / height;
var w = Math.ceil(ratio * width);
if (w > maxWidth) {
var ratio = maxWidth / width;
var h = Math.ceil(ratio * height);
var ret = {
'width': maxWidth,
'height': h
};
} else {
var ret = {
'width': w,
'height': maxHeight
};
}
}
return ret;
}
This will take a width and height of an image, run through some ratio calculations, and spit out a set of dimensions based on maxWidth and maxHeight vars at the top. You can then take the dimensions the method above gives you and apply it to an Image element e.g. :
var dims = logoSize(244,127);
<Image style={[styles.logo, {width:dims.width, height:dims.height}]} source={{uri:'/path/to/image.png}} />
Since the calculations rounds, you may need to apply the resizeMode:'contain' to the styles.logo in your Stylesheet.
Hope this saves someone some time.
I've solved a similar task the following way. First you need to set the initial Image styles:
initialImageStyle : { flex:1, resizeMode:'cover' }
This will render the Image in it's original size that we want to capture in a specific onLayout callback. So the trick is to implement that callback in a following manner:
onLayout (e) {
if (this.state.imageSize) { return }
const { x, y,
height,
width } = e.nativeEvent.layout,
sizeX = width - x,
sizeY = height - y,
imageWidth = (sizeX / sizeY) * IMAGE_HEIGHT
this.setState ({ imageSize: { height: IMAGE_HEIGHT, width: imageWidth, resizeMode: 'contain', }})
}
where IMAGE_HEIGHT is a constant height of your image container. Now all you have to do is just substitute the initial image styles using the state:
<Image
style={ this.state.imageSize || styles.initialImageStyle }
source={ /* your image */ }
onLayout={ this.onLayout.bind (this) }
/>
That's it. In your case you may also need to wrap an image in an additional View. Hope this will help.
Good luck!
It is quite possible but don't expect react-native to take care of everything. You may want to write a small algorithm to make this happen. What resizeMode="contain" does is that it checks whether the size of the image is greater/less than the container. If it is greater than the container, it will be resized to fit the container. If it is smaller than the container, it will be rendered as it is.
Regarding the alignment of the image, react-native doesn't really care. Images are placed at the middle of the container. If you want to place the image left-aligned, you'll have to write a small algorithm which compares the actual dimensions of the image and dimensions of the container.
For eg. If the height of the image is greater than the container, set the height of the image equal to the height of the container and calculate the width of the container using "aspect ratio". Read this to get a clear idea of what you'll have to do.
Also, play with position: 'absolute' to better suit your needs. Good luck!
Edit: Sorry for not deriving a ready-made solution for you. You might find the desired algorithm on google though. I just shoved you in the right direction.