Hide and show the Toolbar according to the scrolling - codenameone

This question is referring to Codename One only.
I need to make the Toolbar of a Codename One Form moving as shown in this video:
https://www.informatica-libera.net/videoLavoro/hideShowToolbarOnScrolling.mp4
As you can see, the scroll up causes the Toolbar to gradually disappear, while the scroll down causes the Toolbar to gradually reappear.
A solution like https://stackoverflow.com/a/55856590 is not applicable because I don't need to change the UIID of the Toolbar, but I need to move the Toolbar up and down during the scroll, to get the same effect shown in the video.

This is the approach we took in the whatsapp clone application for toolbar as that's the exact behavior of whatsapp. There is more to it but this block contains most of the logic that implements this:
private void bindFolding(Container titleArea, int titleHeight,
Container... scrollables) {
addPointerReleasedListener(e -> {
if(titleArea.getHeight() != titleHeight &&
titleArea.getHeight() != 0) {
if(titleHeight - titleArea.getHeight() > titleHeight / 2) {
titleArea.setPreferredSize(null);
} else {
titleArea.setPreferredH(0);
}
titleArea.getParent().animateLayout(100);
}
});
for(Container c : scrollables) {
c.addScrollListener((scrollX, scrollY, oldscrollX,
oldscrollY) -> {
// special case for tensile drag
if(scrollY <= 10) {
titleArea.setPreferredSize(null);
return;
}
int diff = oldscrollY - scrollY;
if(diff > 0) {
if(titleArea.getHeight() < titleHeight) {
titleArea.setPreferredH(Math.min(titleHeight,
titleArea.getPreferredH() + diff));
titleArea.setHeight(titleArea.getPreferredH());
titleArea.getParent().revalidate();
}
} else {
if(diff < 0) {
if(titleArea.getHeight() > 0) {
titleArea.setPreferredH(Math.max(0,
titleArea.getPreferredH() + diff));
titleArea.setHeight(titleArea.getPreferredH());
titleArea.getParent().revalidate();
}
}
}
});
}
}

Related

How to make the 'wheel' event fire once per scroll?

I'm trying to write some React code that detects if a user is scrolling up or down and then increments or decrements a state depending on the direction. I'm using the 'wheel' event because I have a 1 viewport sized page that has the 'overflow: hidden' property on it, so there's no where to actually scroll. Instead, I detect the page to show based on the state mentioned earlier.
Here's what I have so far, but this fires multiple times per scroll instead of just once:
useEffect(() => {
const handleTrackpadSwipe = (event) => {
if (event.deltaY > 0) {
console.log('swiped down')
setTrackpadSwipe('swiped down');
if(pageNumber < 4 ) {
setPageNumber(pageNumber + 1);
}
setTrackpadSwipe('none');
}
else if (event.deltaY < 0) {
console.log('swiped up')
setTrackpadSwipe('swiped up');
if(pageNumber > 1) {
setPageNumber(pageNumber - 1);
}
setTrackpadSwipe('none');
}
};
window.addEventListener('wheel', handleTrackpadSwipe);
}, [trackpadSwipe, pageNumber]);

iOS 11 UINavigationBar bar button items alignment

I am upgrading my application to iOS 11 and I am seeing some problems with the navigation bar, part of my problems have already asked questions here, so I won't mention them in this question.
The particular problem in question is that the navigation bar's bar button items are spaced differently. My main left and right bar button items are closer to the screen's horizontal center now and I can't move them near to the screen edges. In the past I have used a custom UIButton subclass and created bar button items with custom view. The alignment solution were alignmentRectInsets and contentEdgeInsets, now I couldn't manage to produce the expected results using this approach.
Edit:
I have retested with iOS 11 beta 2 and the issue remains.
Edit 2:
I Have retested with iOS beta 3 and the issue remains.
Now in iOS 11 you can manage UINavigationBarContentView to adjust left and right constraints, and UIStackView to adjust buttons (or other elements).
This is my solution for a navigation bar with items on left and right. Also it fixes if you have several buttons together in one side.
- (void) updateNavigationBar {
for(UIView *view in self.navigationBar.subviews) {
if ([NSStringFromClass([view class]) containsString:#"ContentView"]) {
// Adjust left and right constraints of the content view
for(NSLayoutConstraint *ctr in view.constraints) {
if(ctr.firstAttribute == NSLayoutAttributeLeading || ctr.secondAttribute == NSLayoutAttributeLeading) {
ctr.constant = 0.f;
} else if(ctr.firstAttribute == NSLayoutAttributeTrailing || ctr.secondAttribute == NSLayoutAttributeTrailing) {
ctr.constant = 0.f;
}
}
// Adjust constraints between items in stack view
for(UIView *subview in view.subviews) {
if([subview isKindOfClass:[UIStackView class]]) {
for(NSLayoutConstraint *ctr in subview.constraints) {
if(ctr.firstAttribute == NSLayoutAttributeWidth || ctr.secondAttribute == NSLayoutAttributeWidth) {
ctr.constant = 0.f;
}
}
}
}
}
}
}
As you see it is not necessary to add more constraints, as other people have done. There are already defined constraints so they can be changed.
After about two days, here is the simplest and safest solution I could come up with. This solution only works with custom view bar button items, the code for which is included. It is important to note that the left and right margins on the navigation bar have not changed from iOS10 to iOS11 - they are still 16px. Such a large margin makes it difficult to have a sufficiently large click region.
Bar buttons are now layed out with UIStackView's. The prior method of shifting those buttons closer to the margin involved using negative fixed spaces which these stack views cannot handle.
Subclass UINavigationBar
FWNavigationBar.h
#interface FWNavigationBar : UINavigationBar
#end
FWNavigationBar.m
#import "FWNavigationBar.h"
#implementation FWNavigationBar
- (void)layoutSubviews {
[super layoutSubviews];
if (#available(iOS 11, *)) {
self.layoutMargins = UIEdgeInsetsZero;
for (UIView *subview in self.subviews) {
if ([NSStringFromClass([subview class]) containsString:#"ContentView"]) {
subview.layoutMargins = UIEdgeInsetsZero;
}
}
}
}
#end
Using the UINavigationController
#import "FWNavigationBar.h"
UINavigationController *controller = [UINavigationController initWithNavigationBarClass:[FWNavigationBar class] toolbarClass:nil];
[controller setViewControllers:#[rootViewController] animated:NO];
Creating a UIBarButton
Place this code either in a UIBarButton category or in the file you plan on using the bar button which will return an identical looking bar button item using a UIButton.
+ (UIBarButtonItem *)barButtonWithImage:(UIImage *)image target:(id)target action:(SEL)action {
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
//Note: Only iOS 11 and up supports constraints on custom bar button views
button.frame = CGRectMake(0, 0, image.size.width, image.size.height);
button.tintColor = [UIColor lightGrayColor];//Adjust the highlight color
[button setImage:image forState:UIControlStateNormal];
//Tint color only applies to this image
[button setImage:[image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateHighlighted];
[button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
return [[UIBarButtonItem alloc] initWithCustomView:button];
}
Setting the bar button in your controller
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.leftBarButtonItem = [UIBarButtonItem barButtonWithImage:[UIImage imageNamed:#"your_button_image"] target:self action:#selector(leftButtonPressed)];
}
Lastly, I would recommend leaving the left and right margins at zero and just adjusting the position of the button within your image. This will allow for you to take advantage of the full clickable region up to the edge of the screen. The same goes for the height of your image - make sure the height is 44 points.
There is good article on this : http://www.matrixprojects.net/p/uibarbuttonitem-ios11/
Using this we can at least push rightbarbuttonitems to right till it leaves 8 pixel margin from trailing of the UINavigationBar.
Explained really well.
I noticed a similar problem.
I reported an Apple Radar for a similar problem we noticed, #32674764 if you want to refer to it, if you create a Radar.
I also created a thread in Apple's forum, but no feedback yet:
https://forums.developer.apple.com/message/234654
I stumbled upon this: UINavigationItem-Margin.
It works like a charm.
Taken from this answer: BarButtons now use Autolayout and thus require constraints.
if #available(iOS 9.0, *) {
cButton.widthAnchor.constraint(equalToConstant: customViewButton.width).isActive = true
cButton.heightAnchor.constraint(equalToConstant: customViewButton.height).isActive = true
}
Objective C
if (#available(iOS 9, *)) {
[cButton.widthAnchor constraintEqualToConstant: standardButtonSize.width].active = YES;
[cButton.heightAnchor constraintEqualToConstant: standardButtonSize.height].active = YES;
}
Solution 1:
In light of Apple's response that this is expected behavior, we worked around the problem by removing the toolbar and adding a custom view.
I realize that this may not be possible in all cases, but the regular UIView is much easier to customize to the app's appearance than the toolbar and navigation bar where Apple has control of the button positioning.
Instead of setting our custom button as the custom view of the ui bar button object, it was we set it as a subview of the blank ui buttons in the custom view.
Doing this we were able to return to the same look of our ios 10 app
Solution 2:
A bit messy, we wrapped our custom view button in an outer UIButton so the frame location can be set. This does make the outer left edge of the button un-tappable unfortunately, but corrects the look of the button position. See example:
UIButton* outerButton = [UIButton new]; //the wrapper button
BorderedButton* button = [self initBorderedButton]; //the custom button
[button setTitle:label forState:UIControlStateNormal];
[button setFrame:CGRectMake(-10, 0, [label length] * 4 + 35, 30)];
[button addTarget:controller action:#selector(popCurrentViewController) forControlEvents:UIControlEventTouchUpInside];
[outerButton addSubview:button]; //add custom button to outer wrapper button
[outerButton setFrameWidth:button.frameWidth]; //make sure title gives button appropriate space
controller.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:outerButton]; //add wrapper button to the navigation bar
controller.navigationItem.hidesBackButton = YES;
Using that method we keep our navigation bar and can position the button to where it is needed.
Edit: We found that solution 2 does not work on ios 10, this probably will affect only the tiny percent of developers forced to be backward compatible.
Solution 3
What we were really more concerned about with the inward crowding of the buttons was the fact that the title of the navigation bar ran into the custom left button, the size of the margins was less important and used as a tool to make space. The solution is to simply add a spacer item to the left items.
UIBarButtonItem* backButton = [[UIBarButtonItem alloc] initWithCustomView:button];
UIBarButtonItem* spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
controller.navigationItem.leftBarButtonItems = [NSArray arrayWithObjects:backButton, spacer, nil];
Swift version of thedeveloper3214's custom UINavigationBar subclass' layoutSubviews method(https://stackoverflow.com/a/46660888/4189037):
override func layoutSubviews() {
super.layoutSubviews();
if #available(iOS 11, *){
self.layoutMargins = UIEdgeInsets()
for subview in self.subviews {
if String(describing: subview.classForCoder).contains("ContentView") {
let oldEdges = subview.layoutMargins
subview.layoutMargins = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: oldEdges.right)
}
}
}
}
I had the same issue. I had three buttons as right barbutton items on the navigation bar stack view. So, I have updated the insets of the subviews of navigation bar.
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
for view in (self.navigationController?.navigationBar.subviews)! {
view.layoutMargins = UIEdgeInsets.init(top: 0, left: 11, bottom: 0, right: 11)
}
}
Here 11 is the space which I needed. It can be anything as per your requirement.
Also, if you want the buttons with 0 insets, replace view.layoutMargins = UIEdgeInsets.init(top: 0, left: 11, bottom: 0, right: 11) with view.layoutMargins = UIEdgeInsets.zero
Another answer may be help.
My solution : It works in ios 9 - 12. You should call fixNavigationItemsMargin(margin:) in function viewDidAppear(_ animated: Bool) and viewDidLayoutSubviews(). fixNavigationItemsMargin(margin:) would modify the UINavigationController stack.
you could call fixNavigationItemsMargin(margin:) in BaseNavigationController ,do the common work. And call fixNavigationItemsMargin(margin:) in UIViewController do precise layout.
// do common initilizer
class BaseNavigationController: UINavigationController {
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
fixNavigationItemsMargin()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
fixNavigationItemsMargin()
}
}
// do precise layout
class ViewController: UIViewController {
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
navigationController?.fixNavigationItemsMargin(40)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
navigationController?.fixNavigationItemsMargin(40)
}
}
extension UINavigationController {
func fixNavigationItemsMargin(_ margin: CGFloat = 8) {
let systemMajorVersion = ProcessInfo.processInfo.operatingSystemVersion.majorVersion
if systemMajorVersion >= 11 {
// iOS >= 11
guard let contentView = navigationBar.subviews
.first(
where: { sub in
String(describing: sub).contains("ContentView")
}) else { return }
// refer to: https://www.matrixprojects.net/p/uibarbuttonitem-ios11/
// if rightBarButtonItems has not any custom views, then margin would be 8(320|375)/12(414)
// should use customView
let needAdjustRightItems: Bool
if let currentVC = viewControllers.last,
let rightItems = currentVC.navigationItem.rightBarButtonItems,
rightItems.count > 0,
rightItems.filter({ $0.customView != nil }).count > 0 {
needAdjustRightItems = true
} else {
print("Use 8(320|375)/12(414), if need precious margin ,use UIBarButtonItem(customView:)!!!")
needAdjustRightItems = false
}
let needAdjustLeftItems: Bool
if let currentVC = viewControllers.last,
let leftItems = currentVC.navigationItem.leftBarButtonItems,
leftItems.count > 0,
leftItems.filter({ $0.customView != nil }).count > 0 {
needAdjustLeftItems = true
} else {
print("Use 8(320|375)/12(414), if need precious margin ,use UIBarButtonItem(customView:)!!!")
needAdjustLeftItems = false
}
let layoutMargins: UIEdgeInsets
if #available(iOS 11.0, *) {
let directionInsets = contentView.directionalLayoutMargins
layoutMargins = UIEdgeInsets(
top: directionInsets.top,
left: directionInsets.leading,
bottom: directionInsets.bottom,
right: directionInsets.trailing)
} else {
layoutMargins = contentView.layoutMargins
}
contentView.constraints.forEach(
{ cst in
// iOS 11 the distance between rightest item and NavigationBar should be margin
// rightStackView trailing space is -margin / 2
// rightestItem trailing to rightStackView trailing is -margin / 2
let rightConstant = -margin / 2
switch (cst.firstAttribute, cst.secondAttribute) {
case (.leading, .leading), (.trailing, .trailing):
if let stackView = cst.firstItem as? UIStackView,
stackView.frame.minX < navigationBar.frame.midX {
// is leftItems
if needAdjustLeftItems {
cst.constant = margin - layoutMargins.left
}
} else if let layoutGuide = cst.firstItem as? UILayoutGuide,
layoutGuide.layoutFrame.minX < navigationBar.frame.midX {
// is leftItems
if needAdjustLeftItems {
cst.constant = margin - layoutMargins.left
}
}
if let stackView = cst.firstItem as? UIStackView,
stackView.frame.maxX > navigationBar.frame.midX {
// is rightItems
if needAdjustRightItems {
cst.constant = rightConstant
}
} else if let layoutGuide = cst.firstItem as? UILayoutGuide,
layoutGuide.layoutFrame.maxX > navigationBar.frame.midX {
// is rightItems
if needAdjustRightItems {
cst.constant = rightConstant
}
}
default: break
}
})
// ensure items space == 8, minispcae
contentView.subviews.forEach(
{ subsub in
guard subsub is UIStackView else { return }
subsub.constraints.forEach(
{ cst in
guard cst.firstAttribute == .width
|| cst.secondAttribute == .width
else { return }
cst.constant = 0
})
})
} else {
// iOS < 11
let versionItemsCount: Int
if systemMajorVersion == 10 {
// iOS 10 navigationItem.rightBarButtonItems == 0
// space = 16(320|375) / 20(414)
// should adjust margin
versionItemsCount = 0
} else {
// iOS 9 navigationItem.rightBarButtonItems == 0
// space = 8(320|375) / 12(414)
// should not adjust margin
versionItemsCount = 1
}
let spaceProducer = { () -> UIBarButtonItem in
let spaceItem = UIBarButtonItem(
barButtonSystemItem: .fixedSpace,
target: nil,
action: nil)
spaceItem.width = margin - 16
return spaceItem
}
if let currentVC = viewControllers.last,
var rightItems = currentVC.navigationItem.rightBarButtonItems,
rightItems.count > versionItemsCount,
let first = rightItems.first {
// ensure the first BarButtonItem is NOT fixedSpace
if first.title == nil && first.image == nil && first.customView == nil {
print("rightBarButtonItems SPACE SETTED!!! SPACE: ", abs(first.width))
} else {
rightItems.insert(spaceProducer(), at: 0)
// arranged right -> left
currentVC.navigationItem.rightBarButtonItems = rightItems
}
}
if let currentVC = viewControllers.last,
var leftItems = currentVC.navigationItem.leftBarButtonItems,
leftItems.count > versionItemsCount,
let first = leftItems.first {
if first.title == nil && first.image == nil && first.customView == nil {
print("leftBarButtonItems SPACE SETTED!!! SPACE: ", abs(first.width))
} else {
leftItems.insert(spaceProducer(), at: 0)
// arranged left -> right
currentVC.navigationItem.leftBarButtonItems = leftItems
}
}
}
}
}

Continuous Looping Page (Not Infinite Scroll)

I'm looking for resources that create scrolling functions like the ones found on these sites:
Outpost Journal
Unfold
Once the scroll bar hits the bottom of the page, I want it to loop back to the top.
I'm familiar with with the infinite scroll, and this is not what I want. I've also found scripts that will write/add the same content to the bottom of the page, but none that loop back to the top of the page.
Try this:
$('document').ready(function() {
$(document).scroll(function(){
if(document.documentElement.clientHeight +
$(document).scrollTop() >= document.body.offsetHeight )$(document).scrollTop(0);
});
});
if you want infinite scroll in both directions use
if (document.documentElement.clientHeight + $(window).scrollTop() >= $(document).height()) {
$(document).scrollTop(0)
} else if ($(window).scrollTop() < 0) {
$(document).scrollTop($(document).height())
}
(I know it's a late reply but it still helps users like me who just google stuff like this)
Here a solution that makes a duplicate of the body so the bottom and the top can be seen at the same time at a certain point so the transition is smoother.
$('document').ready(function() {
// We need to duplicate the whole body of the website so if you scroll down you can see both the bottom and the top at the same time. Before we do this we need to know the original height of the website.
var origDocHeight = document.body.offsetHeight;
// now we know the height we can duplicate the body
$("body").contents().clone().appendTo("body");
$(document).scroll(function(){ // detect scrolling
var scrollWindowPos = $(document).scrollTop(); // store how far we have scrolled
if(scrollWindowPos >= origDocHeight ) { // if we scrolled further then the original doc height
$(document).scrollTop(0); // then scroll to the top
}
});
});
mrida's answer was causing my browser to not be able to scroll, here is a modified version that worked for me:
$('document').ready(function() {
$(document).scroll(function(){
if (document.documentElement.clientHeight + $(window).scrollTop() >= $(document).height()) {
$(document).scrollTop(0);
}
});
});
Forked from #clankill3r's answer, create two copy of body, prepend and append to the original body, then you can scroll the page in two direction endless.
$('document').ready(function() {
var origDocHeight = document.body.offsetHeight;
var clone=$("body").contents().clone();
clone.appendTo("body");
clone.prependTo("body");
$(document).scroll(function(){
var scrollWindowPos = $(document).scrollTop();
if(scrollWindowPos >= origDocHeight ) {
$(document).scrollTop(0);
}
if(scrollWindowPos <= 0 ) {
$(document).scrollTop(origDocHeight);
}
});
});
Adding loop scroll backwards, upgrading #clankill3r answer. It should be something like this.
$('document').ready(function() {
// We need to duplicate the whole body of the website so if you scroll down you can see both the bottom and the top at the same time. Before we do this we need to know the original height of the website.
var origDocHeight = document.body.offsetHeight;
// now we know the height we can duplicate the body
$("body").contents().clone().appendTo("body");
$(document).scroll(function(){ // detect scrolling
var scrollWindowPos = $(document).scrollTop(); // store how far we have scrolled
if(scrollWindowPos >= origDocHeight ) { // if we scrolled further then the original doc height
$(document).scrollTop(scrollWindowPos + origDocHeight); // then scroll to the top
} else if (scrollWindowPos == 0) { // if we scrolled backwards
$(document).scrollTop(origDocHeight);
}
});
});
I'm using it horizontally and it's working just fine. Hope someone finds it useful.
Posted a similar question: https://stackoverflow.com/a/65953934/7474712 and found the answer via this pen: https://codepen.io/vincentorback/pen/zxRyzj
Here's the code:
<style>
html,
body {
height: 100%;
overflow: hidden;
}
.infinite {
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.clone {
height: 50vw;
}
</style>
<script>
var doc = window.document,
context = doc.querySelector('.infinite'),
clones = context.querySelectorAll('.clone'),
disableScroll = false,
scrollHeight = 0,
scrollPos = 0,
clonesHeight = 0,
i = 0;
function getScrollPos () {
return (context.pageYOffset || context.scrollTop) - (context.clientTop || 0);
}
function setScrollPos (pos) {
context.scrollTop = pos;
}
function getClonesHeight () {
clonesHeight = 0;
for (i = 0; i < clones.length; i += 1) {
clonesHeight = clonesHeight + clones[i].offsetHeight;
}
return clonesHeight;
}
function reCalc () {
scrollPos = getScrollPos();
scrollHeight = context.scrollHeight;
clonesHeight = getClonesHeight();
if (scrollPos <= 0) {
setScrollPos(1); // Scroll 1 pixel to allow upwards scrolling
}
}
function scrollUpdate () {
if (!disableScroll) {
scrollPos = getScrollPos();
if (clonesHeight + scrollPos >= scrollHeight) {
// Scroll to the top when you’ve reached the bottom
setScrollPos(1); // Scroll down 1 pixel to allow upwards scrolling
disableScroll = true;
} else if (scrollPos <= 0) {
// Scroll to the bottom when you reach the top
setScrollPos(scrollHeight - clonesHeight);
disableScroll = true;
}
}
if (disableScroll) {
// Disable scroll-jumping for a short time to avoid flickering
window.setTimeout(function () {
disableScroll = false;
}, 40);
}
}
function init () {
reCalc();
context.addEventListener('scroll', function () {
window.requestAnimationFrame(scrollUpdate);
}, false);
window.addEventListener('resize', function () {
window.requestAnimationFrame(reCalc);
}, false);
}
if (document.readyState !== 'loading') {
init()
} else {
doc.addEventListener('DOMContentLoaded', init, false)
}
</script>

Could an array or two, solve this?

I took over a project and I'm really new to as3! I need to fix an unresolved problem hopefully without starting over from scratch.
I have a contaner_mc, holding four puppet_mc's (puppet_mc1, puppet_mc2, puppet_mc3, puppet_mc4) and each puppet_mc holds four buttons (buddy_bnt_1, buddy_bnt_2, buddy_bnt_3, buddy_bnt_4).
I need the listener to know what button was clicked and from what puppet that button was clicked?
Object(this).contaner_mc.puppet_mc?.buddy_bnt_?.addEventListener(MouseEvent.CLICK, fl_Click);
function fl_Click(event:MouseEvent):void
{
gotoAndPlay(15);
}
Any advice would be greatly appreciated!
Event bubbling should to the magic:
container_mc.addEventListener(MouseEvent.CLICK, click_handler);
function click_handler(event:MouseEvent):void {
if (event.currentTarget == event.target) {
return; // the container is the dispatcher
}
const sprite:Sprite = event.target as Sprite; // just for a typing
if (!sprite) {
trace("event.target is no sprite, set break point here for debugging.");
return;
}
if (sprite.name == 'buddy_bnt_1' || sprite.name == 'puppet_mc1') {
// do something
} else if (sprite.name == 'buddy_bnt_2' || sprite.name == 'puppet_mc2') {
// do something different
} else if (sprite.name == 'buddy_bnt_3' || sprite.name == 'puppet_mc3') {
// do something different
} else if (sprite.name == 'buddy_bnt_4' || sprite.name == 'puppet_mc4') {
// do something different
}
}
container_mc.addEventListener(MouseEvent.CLICK, clickHandler);
function clickHandler(event:MouseEvent):void
{
var clickedObject:DisplayObject = event.target as DisplayObject;
trace (clickedObject.name); // name of button clicked
trace (clickedObject.parent.name); // name of the parent
}
I used DisplayObject so that the code would work with a sprite , movieclip, or any DisplayObject. So make sure you import if you haven't already :
import flash.display.DisplayObject;

Extjs 4: how to change progressbar colour dynamically?

Question Answer below
Hello I'm looking a simple way to change the colour of a progress bar, what I'm trying to do with it, would look like this:
function (progressBar, value) {
if (value < 40) {
progressBar.setColor('red');
} else if (value >= 40 && value <= 80) {
progressBar.setColor('yellow');
} else {
progressBar.setColor('green');
}
}
Then some kind of way to change the colour through the style with the method progressbar already have, setUI, or other kind of way that it could work would be great as well.
Thanks.
Solution
I found the way to do it, here it is, I create a custom progress bar, where I use the listener update, then this one is going to receive the actual value of the progress bar, and the bar itself, I take the obj and find the styles of the progress bar, where I modify backgroundColor and the borderRightColor with the hex color I want and set the backgroundImage to and empty URL then it will allow the backgroundcolor to show up.
Also I create the option to send a default color.
Here is the code:
Ext.define("progressBarCustom", {
extend: 'Ext.ProgressBar',
alias: 'widget.progressBarCustom',
max: null,
ave: null,
min: null,
color: null,
initComponent: function () {
var me = this;
me.width = 300;
me.margin = '5 5 0 5';
me.callParent(arguments);
},
listeners: {
update: function (obj, val) {
if (this.max != null && this.ave != null && this.min != null) {
if (val * 100 <= this.min) {
obj.getEl().child(".x-progress-bar", true).style.backgroundColor = "#FF0000";
obj.getEl().child(".x-progress-bar", true).style.borderRightColor = "#FF0000";
obj.getEl().child(".x-progress-bar", true).style.backgroundImage = "url('')";
} else if (val * 100 <= this.ave) {
obj.getEl().child(".x-progress-bar", true).style.backgroundColor = "#FFFF00";
obj.getEl().child(".x-progress-bar", true).style.borderRightColor = "#FFFF00";
obj.getEl().child(".x-progress-bar", true).style.backgroundImage = "url('')";
} else {
obj.getEl().child(".x-progress-bar", true).style.backgroundColor = "#009900";
obj.getEl().child(".x-progress-bar", true).style.borderRightColor = "#009900";
obj.getEl().child(".x-progress-bar", true).style.backgroundImage = "url('')";
}
} else if (this.color != null) {
obj.getEl().child(".x-progress-bar", true).style.backgroundColor = this.color;
obj.getEl().child(".x-progress-bar", true).style.borderRightColor = this.color;
obj.getEl().child(".x-progress-bar", true).style.backgroundImage = "url('')";
}
}
}
});
Then if you are going to create a new progressbar with the color changes here is the code:
Ext.create('progressBarCustom', {
min : 0.20,
ave : 0.60,
max : 0.80
});
or just with a default color:
Ext.create('progressBarCustom', {
color : "#4D0099"
});
Any suggestion would be received, thanks :).
I would suggest adding a listener that calls your function on the move event as this appears to contain the positions you need. Documentation link.
For the setColor aspect I believe you want to set the components style elements. Documentation link. Hope that helps.

Resources