ActiveReport3 subReport iteration - activereports

how can I
walk cycle for details subreport(2 textboxes) for make a second textbox strictly under the first but right allign.
Or how else would be a way to indicate that the second textbox has been located under the first but right(allign right)
example
good name
price
another good
name
price
`public void Goods_BeforePrint()
{
Section sec;
sec = rpt.Sections["Goods"];
for(int y= 0; y <= sec.Controls.Count - 1;y++)
{
if( y%2> 0)
{
sec.Controls[y].Height += sec.Controls[y-1].Height;
((TextBox)sec.Controls[y]).Text = System.Convert.ToString(sec.Controls.Count);
}
}`
For now I have 0.25 value of Height in every row.
Problem not in allign but in size of rows, because here not have iteration what I expect and each rows is same size = size of first row.

Your question is not very clear; however on the basis of the expected output, I would suggest you to handle the Format event of the SubReport's detail section and access the control which you want to change the alignment for. So if you want it to appear left aligned twice and right aligned for every third row, the following code should work:
int counter = 0;
private void detail_Format(object sender, EventArgs e)
{
counter++;
if (counter % 3 == 0)
{
this.txtCountry1.Alignment = GrapeCity.ActiveReports.Document.Section.TextAlignment.Right;
}
else
{
this.txtCountry1.Alignment = GrapeCity.ActiveReports.Document.Section.TextAlignment.Left;
}
}
Here is a screenshot from my machine showing a basic example with similar implementation.

Related

I have button that execute my method but ignoring the if statement

i have a problem. iam making a game that have button for buy item , and the button have no issue, it run normally, but the problem is the button immediately executes the method without seeing that the method contains an if statement, so what is wrong here Here's the code :
public void TakeMoney()
{
int minusCoin = PlayerInfo.coin -= 5;
PlayerPrefs.SetInt("MyCoinAmount", minusCoin);
}
public void DisableBuyButton()
{
disableBuyButtonRocket3 = 1;
PlayerPrefs.SetInt("DisableBuyButtonRocket3", disableBuyButtonRocket3);
}
public void Buy()
{
int getPlayerCoin = PlayerInfo.coin;
if (getPlayerCoin > 4)
{
if (MyRocket._rocket3 == 1)
{
GetComponent<AudioSource>().Play();
MyRocket._rocket3 = 1;
PlayerPrefs.SetInt("Rocket3Bought", MyRocket._rocket3);
}
}
}
so the button will perform all of the 3 functions above, but as can be seen that I make an if statement so the item can only be purchased if we already have enough money, but when I try I try to reset all values, so my money by default it is 0, but I can buy the item and my money becomes a minus.
Btw, PlayerInfo above is a script from another scene.
Sorry for my bad english.
Your problem is that you do everything in separated methods. It's basically not a problem - but, when you execute them concurrently, it is. Also, your methods are completely independent of each other - an if statement in one will not affect the others' execution. The solution is that you first remove the event listeners to TakeMoney and DisableBuyButton. Then, call them from Buy. If you think it through, it is more logical. Also, remove the temporary variables, as they slow down your code a bit and also make it less readable. Final code could be something like this:
public void TakeMoney()
{
PlayerInfo.coin -= 5;
PlayerPrefs.SetInt("MyCoinAmount", PlayerInfo.coin);
}
public void DisableBuyButton()
{
PlayerPrefs.SetInt("DisableBuyButtonRocket3", 1);
}
public void Buy()
{
if (PlayerInfo.coin > 4) {
TakeMoney();
DisableBuyButton();
if (MyRocket._rocket3 != 1 /* changed this, because it seemed that you want to check whether it is NOT one */)
{
GetComponent<AudioSource>().Play();
// I changed the if statement because this
MyRocket._rocket3 = 1;
PlayerPrefs.SetInt("Rocket3Bought", MyRocket._rocket3);
}
}
}
the playerinfo.coin value would be more than 4 because it will decrease coin at click so it will minus only 5 at a click you could check playerinfo.coin value

Hw to Freeze the Button in Scroll bar

I am using unity 2018.3.7. In my project I have instantiate 25 buttons in the scroll bar..I am scrolling the button. It is working well.
Actually i want freeze the 12 the button.When i scroll the button. The 12 th button should be constantly should be there and other button should scroll go up.
scrolling should be done but the freeze button should be constantly there.
Like Excel. If we freeze the top row. The top row is constantly there and scrolling is happened.
Like that i have to do in unity.
How to Freeze the button in scroll bar.
Edit:
Actually I have uploaded new gif file. In that gif file 2 row is freezed (Row Heading1,Row Heading2, Row Heading3,RowHeading4).
2nd row is constantly there. Rest of the the rows 4 to 100 rows are going up.
Like that i have to do ...
How can i do it..
Though your question still is very broad I guess I got now what you want. This will probably not be exactly the solution you want since your question is quite vague but it should give you a good idea and starting point for implementing it in the way you need it.
I can just assume Unity UI here is the setup I would use. Since it is quite complex I hope this image will help to understand
so what do we have here:
Canvas
has the RowController script attached. Here reference the row prefab and adjust how many rows shall be added
Panel is the only child of Canvas. I just used it as a wrapper for having a custom padding etc - it's optional
FixedRowPanel
Here we will add the fixed rows on runtime
Initially has a height of 0!
Uses anchore pivot Y = 1! This is later important for changing the height on runtime
Uses a Vertical Layout Group for automatically arranging added children
ScrollView - Your scrollview as you had it but
Uses streched layout to fill the entire Panel (except later the reduced space for the fixed rows)
Uses anchor pivot Y = 1! Again important for changing the height and position on runtime later
Viewport afaik it should already use streched anchors by default but not sure so make it
Content
Uses a Vertical Layout Group
Initially has a height of 0 (but I set this in the code anyway) and will grow and shrink accordingly when adding and removing rows
And finally RowPrefab
I didn't add its hierachy in detail but it should be clear. It has a Toggle and a Text as childs ;)
Has the Row script attached we use for storing and getting some infos
Now to the scripts - I tried to comment everything
The Row.cs is quite simple
public class Row : MonoBehaviour
{
// Reference these via the Inspector
public Toggle FixToggle;
public Text FixTogText;
public Text RowText;
public RectTransform RectTransform;
// Will be set by RowController when instantiating
public int RowIndex;
private void Awake()
{
if (!RectTransform) RectTransform = GetComponent<RectTransform>();
if (!FixToggle) FixToggle = GetComponentInChildren<Toggle>(true);
if (!FixTogText) FixTogText = FixToggle.GetComponentInChildren<Text>(true);
}
}
And here is the RowController.cs
public class RowController : MonoBehaviour
{
public Row RowPrefab;
public RectTransform ScrollView;
public RectTransform Content;
public RectTransform FixedRowParent;
public int HowManyRows = 24;
public List<Row> CurrentlyFixedRows = new List<Row>();
public List<Row> CurrentlyScrolledRows = new List<Row>();
// Start is called before the first frame update
private void Start()
{
// initially the content has height 0 since it has no children yet
Content.sizeDelta = new Vector2(Content.sizeDelta.x, 0);
for (var i = 0; i < HowManyRows; i++)
{
// Create new row instances and set their values
var row = Instantiate(RowPrefab, Content);
// store the according row index so we can later sort them on it
row.RowIndex = i;
row.RowText.text = $"Row Number {i + 1}";
// add a callback for the Toggle
row.FixToggle.onValueChanged.AddListener(s => HandleToggleChanged(row, s));
// increase the content's size to fit the children
// if you are using any offset/padding between them
// you will have to add it here as well
Content.sizeDelta += Vector2.up * row.RectTransform.rect.height;
// don't forget to add them to this list so we can easily access them
CurrentlyScrolledRows.Add(row);
}
}
// called every time a row is fixed or unfixed via the Toggle
private void HandleToggleChanged(Row row, bool newState)
{
if (newState)
{
// SET FIXED
// Update the button text
row.FixTogText.text = "Unfix";
// Move this row to the fixedRow panel
row.transform.SetParent(FixedRowParent);
// be default we assume we want the first position
var targetIndex = 0;
// if there are other fixed rows already find the first child of FixedRowParent that has a bigger value
if (CurrentlyFixedRows.Count > 0) targetIndex = CurrentlyFixedRows.FindIndex(r => r.RowIndex > row.RowIndex);
// handle case when no elements are found -> -1
// this means this row is the biggest and should be the last item
if (targetIndex < 0) targetIndex = CurrentlyFixedRows.Count;
// and finally in the hierachy move it to that position
row.transform.SetSiblingIndex(targetIndex);
// insert it to the fixed list and remove it from the scrolled list
CurrentlyFixedRows.Insert(targetIndex, row);
CurrentlyScrolledRows.Remove(row);
// Make the fixed Panel bigger about the height of one row
FixedRowParent.sizeDelta += Vector2.up * row.RectTransform.rect.height;
// Make both the scrollView and Content smaller about one row
Content.sizeDelta -= Vector2.up * row.RectTransform.rect.height;
ScrollView.sizeDelta -= Vector2.up * row.RectTransform.rect.height;
// Move the scrollView down about one row in order to make space for the fixed panel
ScrollView.anchoredPosition -= Vector2.up * row.RectTransform.rect.height;
}
else
{
// SET UNFIXED - Basically the same but the other way round
// Update the button text
row.FixTogText.text = "Set Fixed";
// Move this row back to the scrolled Content
row.transform.SetParent(Content);
// be default we assume we want the first position
var targetIndex = 0;
// if there are other scrolled rows already find the first child of Content that has a bigger value
if (CurrentlyScrolledRows.Count > 0) targetIndex = CurrentlyScrolledRows.FindIndex(r => r.RowIndex > row.RowIndex);
// handle case when no elements are found -> -1
// this means this row is the biggest and should be the last item
if (targetIndex < 0) targetIndex = CurrentlyScrolledRows.Count;
// and finally in the hierachy move it to that position
row.transform.SetSiblingIndex(targetIndex);
// insert it to the scrolled list
CurrentlyScrolledRows.Insert(targetIndex, row);
// and remove it from the fixed List
CurrentlyFixedRows.Remove(row);
// shrink the fixed Panel about ne row height
FixedRowParent.sizeDelta -= Vector2.up * row.RectTransform.rect.height;
// Increase both Content and Scrollview height by one row
Content.sizeDelta += Vector2.up * row.RectTransform.rect.height;
ScrollView.sizeDelta += Vector2.up * row.RectTransform.rect.height;
// Move scrollView up about one row height to fill the empty space
ScrollView.anchoredPosition += Vector2.up * row.RectTransform.rect.height;
}
}
}
Result:
As you can see I can now fix and unfix rows dynamically while keeping their correct order within both according panels.

Accessing CSV row when using a class

*Edited with advise from below. STill working on minisming the code more. *
I am attempting to shift to using classes in my code. I have this functioning in a larger piece of code and I'm attempting to recreate the stepping action now using a class.
if (i< table.getRowCount()) {
row = table.getRow(i);
k=row.getInt("y");
x=row.getInt("x");
}
//draw white ellipse visual
ellipse(x*diam, y, diam, diam);
// step next circle up
y+=Step;
// -- if off the set upper limit of the line,
// swing right
if (frameCount%(k/Step)==0) {
x+=Step;
y=starty;
// increment row counter
i=i+1;
}
I am trying to troubleshoot why I am unable to step through variable i as the rows in the csv table.
I am expecting k to print out the data in column named "y" in the csv file.
I am expecting i to print out a number incrementing by 1 each time variable y reaches the value of k.
From printing out my variables i,k,x
k is successfully getting the data from csv file column named "y"
x is successfully getting the data from csv file column named "x"
y is successfully incrementing
i is not incrementing
y is not registering it has reached k.
my thoughts right now are that actually variable k is a marker for y to stop incrementing but should perhaps not be part of the Dot parameters in the constructor.
// An Array of Dot objects
Dot[] dots;
// A Table object
Table table;
float diam=10.0;
int i;
void setup() {
size(560, 420);
loadData();
background(0);
// set the animation speed
frameRate(10);
}
void draw() {
// Display all dots
for (Dot d : dots) {
d.display();
d.move();
}
}
void loadData() {
// Load CSV file into a Table object
// "header" option indicates the file has a header row
table = loadTable("data.csv", "header");
// The size of the array of Dot objects is determined by the total number of rows in the CSV
dots = new Dot[table.getRowCount()];
// You can access iterate over all the rows in a table
int rowCount = 0;
for (TableRow row : table.rows()) {
// You can access the fields via their column name (or index)
if (i< table.getRowCount()) {
row = table.getRow(i);
float x = row.getFloat("x");
float k = row.getFloat("y");
float d = row.getFloat("diameter");
//String n = row.getString("name");
// Make a fot object out of the data read
dots[rowCount] = new Dot(i,k, x, d);
rowCount++;
}
}
// check to see if at end of data
if (i == table.getRowCount()) {
i = 0;//if so, loop back to first row
}
}
class Dot {
float x =10.0;
float y=10.0;
float diam=10.0;
float k;
int step=10;
int startx =10;
int starty=10;
float i=0;
Dot(float i_,float k_, float x_,float diam_) {
k=k_;
x=x_;
i=i_;
diam=diam_;
}
void display() {
noStroke();
fill(255);
// draw a circle
ellipse(x*diam, y, diam, diam);
}
void move() {
// move next circle to the right
y+=step;
// -- if off the right edge of the line,
// swing down and all the way to the left
if (frameCount%(k/step)==0) {
x+=step;
y=starty;
// increment row counter
i=i+1;
}
// if off the bottom of the page, stop
if (x>=width) {
fill(0);
text("done", width/2, height/2);
noLoop();
}
}
}

Why comparing float values is such difficult?

I am newbie in Unity platform. I have 2D game that contains 10 boxes vertically following each other in chain. When a box goes off screen, I change its position to above of the box at the top. So the chain turns infinitely, like repeating Parallax Scrolling Background.
But I check if a box goes off screen by comparing its position with a specified float value. I am sharing my code below.
void Update () {
offSet = currentSquareLine.transform.position;
currentSquareLine.transform.position = new Vector2 (0f, -2f) + offSet;
Vector2 vectorOne = currentSquareLine.transform.position;
Vector2 vectorTwo = new Vector2 (0f, -54f);
if(vectorOne.y < vectorTwo.y) {
string name = currentSquareLine.name;
int squareLineNumber = int.Parse(name.Substring (11)) ;
if(squareLineNumber < 10) {
squareLineNumber++;
} else {
squareLineNumber = 1;
}
GameObject squareLineAbove = GameObject.Find ("Square_Line" + squareLineNumber);
offSet = (Vector2) squareLineAbove.transform.position + new Vector2(0f, 1.1f);
currentSquareLine.transform.position = offSet;
}
}
As you can see, when I compare vectorOne.y and vectorTwo.y, things get ugly. Some boxes lengthen and some boxes shorten the distance between each other even I give the exact vector values in the code above.
I've searched for a solution for a week, and tried lots of codes like Mathf.Approximate, Mathf.Round, but none of them managed to compare float values properly. If unity never compares float values in the way I expect, I think I need to change my way.
I am waiting for your godlike advices, thanks!
EDIT
Here is my screen. I have 10 box lines vertically goes downwards.
When Square_Line10 goes off screen. I update its position to above of Square_Line1, but the distance between them increases unexpectedly.
Okay, I found a solution that works like a charm.
I need to use an array and check them in two for loops. First one moves the boxes and second one check if a box went off screen like below
public GameObject[] box;
float boundary = -5.5f;
float boxDistance = 1.1f;
float speed = -0.1f;
// Update is called once per frame
void Update () {
for (int i = 0; i < box.Length; i++) {
box[i].transform.position = box[i].transform.position + new Vector3(0, speed, 0);
}
for (int i = 0; i < box.Length; i++)
{
if(box[i].transform.position.y < boundary)
{
int topIndex = (i+1) % box.Length;
box[i].transform.position = new Vector3(box[i].transform.position.x, box[topIndex].transform.position.y + boxDistance, box[i].transform.position.z);
break;
}
}
}
I attached it to MainCamera.
Try this solution:
bool IsApproximately(float a, float b, float tolerance = 0.01f) {
return Mathf.Abs(a - b) < tolerance;
}
The reason being that the tolerances in the internal compare aren't good to use. Change the tolerance value in a function call to be lower if you need more precision.

Pure ActionScript 3.0 - Memory Game

I'm a beginner of ActionScript 3.0. I'm making a simple memory game, the tool I'm using is Eclipse with flexsdk plugin. Right now I've done the shuffle and display images, and the cover of the images as well.
My idea is when clicking on the image, the cover will remove and show the image behind of it. After 2 covers are gone, the game will compare and check whether the selected images are match or not, if match both of the images will remain, otherwise the cover will reappear and the game keeps going on. If all of the images are match, a winning line will appear.
The problem I'm facing is I got no idea on how to deal with the images comparison part. I wanted to compare with the index number of array or the name of the images, but I really don't have any idea. I've refer some examples but all of them are develop in CS3 and uses the timeframe which is not exist in pure ActionScript.
package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import myclasses.Cover;
public class Prototype extends Sprite {
protected static const WIDTH:int=3;
protected static const HEIGHT:int=2;
protected static const SPACINGX:int=100;
protected static const SPACINGY:int=74;
protected static const OFFSETX:int=96;
protected static const OFFSETY:int=100;
protected static const SIZE:Number=100;
protected static const COLOUR:uint=0x999999;
[Embed(source="images/pic1.jpg")]
protected static const PIC1:Class;
[Embed(source="images/pic2.jpg")]
protected static const PIC2:Class;
[Embed(source="images/pic3.jpg")]
protected static const PIC3:Class;
protected var imagesList:Array=[PIC1,PIC1,PIC2,PIC2,PIC3,PIC3];
protected var X:int;
protected var Y:int=27;
protected var count:int;
//protected var firstTap:Class;
//protected var secondTap:Class;
public function Prototype() {
var shuffled:Array = shuffleList(imagesList.length);
for(var i:int; i<imagesList.length; i++) {
//var colour:uint;
//colour=0x999999;
var j:int = shuffled[i];
var thing:Sprite=new Sprite();
thing.addChild(new imagesList[j]());
thing.x=X;
thing.y=Y;
addChild(thing);
new Cover(this,X,Y,SIZE,COLOUR);
X=X+SPACINGX+OFFSETX;
count++;
if(count == WIDTH){
Y=Y+SPACINGY+OFFSETY;
X=0;
}
addEventListener(MouseEvent.MOUSE_DOWN,selectImages);
}
}
public function selectImages(event:MouseEvent):void {
//(P/S: this is not the actual code)
var target:Sprite = Sprite(event.target)
if(firstTap == null){
firstTap = ; //1st selected image
removeChild(target);
}else if(secondTap == null){
secondTap = ; //2nd selected image
if(firstTap == secondTap){
firstTap = null;
secondTap = null;
}else{
//firstTap = ; //cover back
//secondTap = ; //cover back
secondTap = null;
firstTap = ; //selected another image
}
}
}
protected function shuffleList(n:Number):Array {
var startList:Array = new Array(n);
var endList:Array = new Array(n);
var i:Number, j:Number;
for (i=0; i<n; i++) {
startList[i] = i;
}
for (i=0; i<n; i++) {
j = Math.floor(Math.random()*startList.length);
endList[i] = startList.splice(j,1)[0];
}
return(endList);
}
}
}
Please help me figure out. Thanks.
Well I didn't really go through your code in details, but from looking at it, it seems you are making things really complex. So let me give you a hint in how I would do it...
1) First I would make a 'card' class, which extends sprite or bitmap, mainly containing the image of that card, image of the cover/mask, some animtion methods like hide/show e.t.c, and possibly an 'id' variable to recognize it later, though that is not needed. You can also get away with the array you have, and in that case, skip step 2.
2) Now push two copies of each card in an array.
example [new card('c1'),new card('c1'),new card('c2'),new card('c2'),.....].
3) Now comes the part where you made it most complex, that is, the shuffling of the array. Let's write a custom function for it, shall we?
function shuffleArr(arr):Array
{
var len:int = arr.length();
for(var i:int=0; i<len; i++)
{
//Swap the value at i with a random value within the array;
var tmp_pos:int = Math.floor(Math.random()*len);
while(tmp_pos==i)
{
tmp_pos = Math.floor(Math.random()*len);
}
var tmp_var:card = arr[tmp_pos];
arr[tmp_pos] = arr[i];
arr[i] = tmp_var;
}
}
4) Now that the array is shuffled, you simply have to lay them out in a grid.
for(var row:int=0; row<6; row++)
{
for(var col:int=0; col<6; col++)
{
card_arr[i].x = card_arr[i].width*cols+5;
card_arr[i].y = card_arr[i].height*row+5;
stage.addChild(card[i]);
}
}
5) Now you have to check for user click and take action, and there are many ways to do it, but I will tell one of them...
a) Give the cards a click event handler, this becomes easy if the cards are a class, or you can look into event.target property and use a general click handler. it's up to you.
b) On click, push the card's id in an array. If you did make them into a class, their ids should now be, c1, c2, e.t.c, and you can do
holder_arr.push(this);
this.removeCover();
6) Now you have to make sure, that the holder array can only hold two values at a time. Then do the checking. I am writing a semi-pseudo code with a lot of assumed functions and values:
//Insert
if(holder_arr.length()==2)
{
//flip back the cards and empty the array
holder_arr[0].showCover();
holder_arr[1].showCover();
holder_arr = [];
}
holder_arr.push(this);
...
..
7) For checking make a function and run it every time a card is clicked, and also when a timer ends, to flip back the cards.
function checkCards()
{
if(holder_arr.length==2)
{
if(holder_arr[0].id==holder_arr[1].id)
{
//the cards match
holder_arr[0].vanishAnim();
holder_arr[1].vanishAnim();
holder_arr=[];
}
else
{
holder_arr[0].showCover();
holder_arr[1].showCover();
holder_arr=[];
}
}
}
Obviously you will remove the cards from the actual card_arr too, but when to do that is up to you to figure out ;)
Personally , I find the problem has more to do with the way you shuffle your cards as it makes it a bit more difficult to identify what card is what.
Let's say for instance that instead of shuffling your embed assets , you were first creating your cards , naming them after the image they add , then creating an Array ( or Vector ) of cards and shuffle that Array ( or Vector ), identifying the cards would be fairly easy since you'd only have to compare their name property.
//PSEUDO CODE
- create Array ( Vector ) of embed assets [PIC1, PIC2 , PIC3]
- create cards and use Array ( Vector ) index to identify
each card with the name property
- create a set of six cards
- shuffle set