How to implement Steps progress bar in Codenameone? - codenameone

I would be grateful for any hints/examples on how to create a Steps Progress Bar using Codenameone and similar to:
https://github.com/YablokovDmitry/StepViewPager

You can just use toggle buttons to represent every step in either box or flow layout. Roughly something like this (didn't test it):
public Container createSteps(String[] labels, ActionListener[] actions) {
Container cnt = new Container(BoxLayout.x();
CheckBox[] steps = new CheckBox[labels.length];
for(int iter = 0 ; iter < steps.length ; iter++) {
steps[iter] = CheckBox.createToggle(labels[iter]);
steps[iter].setTextPosition(BOTTOM);
steps[iter].setMaterialIcon(FontImage.MATERIAL_CHECK_CIRCLE);
steps[iter].addActionListener(actions[iter]);
steps[iter].addActionListener(e -> {
for(int x = 0 ; x < steps.length ; x++) {
if(x != iter) {
steps[x].setSelected(x < iter);
}
}
});
if(iter > 0 && iter < steps.length - 1) {
cnt.add(new Label("---"));
}
cnt.add(steps[iter]);
}
return cnt;
}
You can determine the color via styling on the pressed and default styling. You can also have the loop above customize things like different icons for every stage.

Related

Hide and show the Toolbar according to the scrolling

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();
}
}
}
});
}
}

Knockout add an item to an array conditionally

My application is MVC5. Using Ajax I am getting the array from Database, works well. However when I check if the value of specific item is not null and try to add it to the array it does not add it. I am using the following:
if (result && result.ohaMed.length > 0) {
for (var l = 0; l < result.ohaMed.length; l++) {
self.ohaitems.push({ OhaTypeId: result.ohaMed[l].OhaTypeId, Name: result.ohaMed[l].Name});
if (result.ohaMed[l].InfoURL != null) {
if (self.ohaitems.indexOf(result.ohaMed[l].InfoURL) < 0) {
self.ohaitems.push({ InfoURL: result.ohaMed[l].InfoURL });
}
};
};
};
If I add InfoURL as part of the first push it works.

KendoUI Treeview with AngularJS uncheck checkboxes

I'm using KendoUI (v2015.1.318) with AngularJS (v1.3.14). After every click on a node, the data will be fetched from an API.
After selecting some items and clicking on the button "add", the items will be added in a seperated list, the expanded treenodes must stay visible but all the
checked items must be unchecked.
After I iterated through the datasource to uncheck the checked items , I have call SetDataSource again. When I have expanded a lot of nodes and checked a few, the UI freezes some seconds while it's processing.
I was wondering if there wasn't a more efficient way to execute this.
I made an example without API call:
$scope.saveTreeFields = function () {
var data = $scope.tree.dataSource._data;
for (var i = 0, j = data.length; i < j; i++) {
checkChildren(data[i]);
}
function checkChildren(data) {
if (data.checked) {
data.checked = false;
}
if (data.items !== undefined) {
for (var i = 0, j = data.items.length; i < j; i++) {
checkChildren(data.items[i]);
}
}
}
$scope.tree.setDataSource(data)
};
Plunker example
Received an answer from Telerik itself.
you can call the dataItem set("checked", false) method to notify the
model of the field change, and the TreeView will update automatically.
Code changes
$scope.saveTreeFields = function () {
var data = $scope.tree.dataSource.data();
for (var i = 0, j = data.length; i < j; i++) {
checkChildren(data[i]);
}
function checkChildren(data) {
if (data.checked) {
data.set("checked", false);
}
if (data.items !== undefined) {
for (var i = 0, j = data.items.length; i < j; i++) {
checkChildren(data.items[i]);
}
}
}
};

Actionscript 3.0 : Controlling child movieclips added with an array

I'm trying to build a generic slide show flash file controlled with key presses... right and left arrow to go to next / previous slide, down and up to call / uncall the single animations / bullet points / whatever on a single slide.
So far I managed to get a file that can load all the pages from a movieclip and flick through them with right and left arrow and a nice fade out and fade in effect, even when flicking very fast.
What I do not get at all after several hours and lots of google searches is how to now control the single page movieclips. I uploaded the file so far:
http://www.broesel-brzelius.de/zeug/slide.zip
You can see that my (as of yet crude) attempt to control the pageHolder.Pages.page1 movieclip to gotoAndStop(2) just results in the pageHolder.Pages movieclip that was loaded to position 0 in the array to go to frame 2 and thus display the second page.
Code so far:
import flash.display.Sprite;
import flash.events.MouseEvent;
import com.greensock.*;
import flash.display.MovieClip;
// instantiate a variable to find number of pages
var numberOfPages:Pages = new Pages();
// instantiate an array to hold the page movieclips
var pageArray:Array = new Array();
// instantiate a container to hold the pages
var pageHolder:Sprite = new Sprite();
// declare variables that will hold reference to the current page IDs
var targetIDold:int = 0;
var targetIDnew:int = 0;
// declare a variable that will hold the current direction of slide movement
var movement:int = -1;
// call a function that builds the application
// pass in the number of pages in fl_prevSlide
buildApp(numberOfPages.totalFrames);
// this function builds the application
function buildApp(n:int):void
{
// declare variables for the pages
var p:Pages;
// instantiate a new Page, send its playhead to the current value of i+1
// it is necessary to add 1 to the value of i, since i starts at 0, while the timeline starts at 1
for (var i:int = 0; i < n; i++)
{
p = new Pages();
p.gotoAndStop(i + 1);
pageArray.push(p);
}
// set the position of the pageHolder relative to the buttonHolder
pageHolder.x = pageHolder.y = 0;
// add the first page (at index 0) from pageArray to pageHolder
pageHolder.addChild(pageArray[targetIDnew]);
// add pageHolder and buttonHolder to the stage
addChild(pageHolder);
}
//Adding Listener and corresponding function to change between slides
stage.addEventListener(KeyboardEvent.KEY_DOWN, f_changeSlide);
function f_changeSlide(evt:KeyboardEvent):void
{
if(evt.keyCode == 37) // left arrow
{
f_prevSlide();
}
else if (evt.keyCode == 39 || evt.keyCode == 32) // right arrow or space
{
f_nextSlide();
}
}
function f_prevSlide():void
{
if(targetIDnew > 0)
{
movement = -1;
targetIDnew -= 1;
f_addPage();
}
}
function f_nextSlide():void
{
if(targetIDnew < (numberOfPages.totalFrames - 1))
{
movement = 1;
targetIDnew += 1;
f_addPage();
}
}
function f_addPage():void
{
// use the targetID variable to access the corresponding index in the pageArray and assign it to a temporary variable
targetIDold = targetIDnew - movement;
var _mcOld:MovieClip = MovieClip(pageArray[targetIDold]);
var _mcNew:MovieClip = MovieClip(pageArray[targetIDnew]);
//avoid flickering
if (_mcNew.alpha == 1) {
_mcNew.alpha = 0;
}
// add the temp variable to pageHolder
pageHolder.addChild(_mcNew);
// tween the temp variable to the specified properties, then call a function to remove the previous page
// new page gets faded in, old page gets faded out
TweenMax.to(_mcNew, 1.5, {alpha:1});
TweenMax.to(_mcOld, 1.5, {alpha:0, onComplete:f_removePage});
}
function f_removePage():void
{
// previous page will always be at index 0; remove it
// the new page just added will drop down to index 0 when the previous page is removed
pageHolder.removeChildAt(0);
}
//Trying to advance / decrease the timeline in the movieclips of the single pages by pressing down / up
stage.addEventListener(KeyboardEvent.KEY_DOWN, f_changeFrame);
function f_changeFrame(evt:KeyboardEvent):void
{
if(evt.keyCode == 40) // down arrow
{
f_nextFrame();
}
else if (evt.keyCode == 38) // up arrow
{
f_prevFrame();
}
}
function f_nextFrame():void
{
var w:uint = pageHolder.numChildren - 1 ;
(pageHolder.getChildAt(w) as MovieClip).gotoAndStop(currentFrame + 1);
// for (var i:uint = 0; i < pageHolder.numChildren; i++)
// {
// trace (+i+'.\t name:' + pageHolder.getChildAt(i).name + '\t type:' + typeof (pageHolder.getChildAt(i)));
// }
trace ("down!");
}
function f_prevFrame():void
{
var w:uint = pageHolder.numChildren - 1 ;
(pageHolder.getChildAt(w) as MovieClip).gotoAndStop(currentFrame - 1);
// for (var i:uint = 0; i < pageHolder.numChildren; i++)
// {
// trace (+i+'.\t name:' + pageHolder.getChildAt(i).name + '\t type:' + typeof (pageHolder.getChildAt(i)));
// }
trace ("up!");
}
Edit: clarified code a bit
Edit2: TL;DR: Problem is the last bit of code with the three functions that fail to control the timeline of mc page1, which is a child of mc pages, which is pushed frame by frame into an array and loaded at runtime into the sprite pageHolder. How to control the timeline of the single page movieclips?
Finally got it to work. This will work as a perfect powerpoint replacement :D
You will need to name the single slides (one movieclip on each frame of the mc pages) as page0, page1 etc. and then can control their timeline with this code (just replace the functions listed in the question above):
function f_nextFrame():void
{
var temp:uint = pageHolder.numChildren - 1;
var frame:uint = ((pageHolder.getChildAt(temp) as MovieClip)["page" + targetIDnew].currentFrame);
(pageHolder.getChildAt(temp) as MovieClip)["page" + targetIDnew].gotoAndStop(frame + 1);
}
function f_prevFrame():void
{
var temp:uint = pageHolder.numChildren - 1;
var frame:uint = ((pageHolder.getChildAt(temp) as MovieClip)["page" + targetIDnew].currentFrame);
(pageHolder.getChildAt(temp) as MovieClip)["page" + targetIDnew].gotoAndStop(frame - 1);
}

Customize TDBNavigator buttons in C++ builder

Is there a way how to add caption to a TDBNavigator button in C++ builder ?
This will allow you to add captions to each button in c++ builder
char *btntext[11] = {"First","Prior","Next","Last","Insert","Delete","Edit","Post","Cancel","Refresh","Apply"};
for(int x = 0; x < nav->ComponentCount; ++x)
{
TNavButton* navbutton = dynamic_cast<TNavButton *>( nav->Components[ x ] );
if( navbutton )
{
navbutton->Font->Name = "Arial";
navbutton->Font->Size = 8;
navbutton->Caption = btntext[x];
navbutton->Spacing = 0;
navbutton->Layout = blGlyphTop;
}
}
here you have a full example of how to do it
http://delphi.about.com/od/usedbvcl/l/aa090203a.htm
it is written in Delphi, but the code can easily adapted to c++ builder.

Resources