I have a text that appears, when the game starts. But once the obj_cover is destroyed, I would like another text to appear. So how can I do that?
If you want change one text to another, you can do something like
if instance_exists(obj_cover)
var txt = "text 1";
else
var txt = "text 2";
draw_text(posx, posy, txt);
If you want simple show text when obj_cover is destroyed, you can do, for example, this:
Create object obj_text. Add to Create event:
text = "";
Draw event:
// also here you can define color, font, align, etc
draw_text(x, y, text);
Now add to obj_cover, Destroy event:
var obj = instance_create(posx, posy, obj_text);
obj.text = "your text";
Other way - you can use a variable for checking, is need draw text or not. For example, Destroy event of obj_cover:
global.show_text = false;
And somewhere in other object:
if global.show_text
draw_text(posx, posy, "text");
etc...
Very many ways possible.
Related
Is it possible to allow the user to dynamically show or hide columns in the Table widget? Or would that require creating a custom table? If a custom table, what would the basic steps for that be?
Any assistance is much appreciated. Thank you.
In AppMaker, there are no columns, only rows. The way you organize the widgets inside the rows is what gives you the column like display. But to answer your question... YES, it is possible to allow the user to dynamically hide and show columns in a table widget and it's very very very easy to achieve.
Take into consideration the following example as a demo:
Say you have a datasource with three fields; name, email and assignments. In a new page in app maker, drop a table widget towards the center of the canvas and select that as its datasource. Then add three button widgets on top of the table widget and align them horizontally. Change the text widget of the left button to "Hide Name". Then change the text of the middle button to "Hide Emails" and then change the text of the right button to "Hide Assigns". It should resemble something like this:
Now, click the left label widget inside the table row (not inside the table header), and change its name property to "name". Do similar with the middle label widget and change its name property to "email" and also with the right label widget changing its name property to "assign". Take a look at the example below:
Next, we need to add some logic to the onClick events of our button that will dynamically show and hide the columns. Click on the "Hide Name" button and and the following code to the onClick event:
var visibility;
if(widget.text === "Hide Name"){
widget.text = "Show Name";
visibility = false;
} else {
widget.text = "Hide Name";
visibility = true;
}
var table = widget.root.descendants.Table1.descendants;
table.Table1nameHeader.visible = visibility;
var tableRows = table.Table1Body.children._values;
for(var i=0; i<tableRows.length; i++){
var row = tableRows[i];
row.children.name.visible = visibility;
}
We also need to add similar code to the "Hide Email" button. Click on that button and add the following code to the onClick event:
var visibility;
if(widget.text === "Hide Email"){
widget.text = "Show Email";
visibility = false;
} else {
widget.text = "Hide Email";
visibility = true;
}
var table = widget.root.descendants.Table1.descendants;
table.Table1emailHeader.visible = visibility;
var tableRows = table.Table1Body.children._values;
for(var i=0; i<tableRows.length; i++){
var row = tableRows[i];
row.children.email.visible = visibility;
}
And finally, we do the same thing with the "Hide Assigns" button. Click on it and add the following code to the onClick event:
var visibility;
if(widget.text === "Hide Assigns"){
widget.text = "Show Assigns";
visibility = false;
} else {
widget.text = "Hide Assigns";
visibility = true;
}
var table = widget.root.descendants.Table1.descendants;
table.Table1assignmentsHeader.visible = visibility;
var tableRows = table.Table1Body.children._values;
for(var i=0; i<tableRows.length; i++){
var row = tableRows[i];
row.children.assign.visible = visibility;
}
That should be all. It's time to preview the app. Please do so and the result should be something like this:
I hope it helps!
One more alternative to the solution provided by Morfinismo is rendering dynamic tables. The idea is to render table's header using Grid Widget and to render table's body using List Widget with Grid inside each row. Grid's datasources could be populated using Model's Metadata. More details and screenshots could be found in option #4 in this answer.
How do I recognize a double click on a tab in order to change its label?
Preferrably I could edit the label in place but alternatively I could also get a string from another input box. Any suggestions?
The tab gets added and the label specified currently like:
QString tab_label = QString("Shell (") + QString::number(session->id(), 16) + ")";
addTab(session->widget(), tab_label);
and I'd want to be able to edit the label after creation.
Oh and I should mention here that I'm a Qt newbie, too!
EDIT1
full method:
int SessionStack::addSession(Session::SessionType type)
{
Session* session = new Session(type, this);
connect(session, SIGNAL(titleChanged(int,QString)), this, SIGNAL(titleChanged(int,QString)));
connect(session, SIGNAL(terminalManuallyActivated(Terminal*)), this, SLOT(handleManualTerminalActivation(Terminal*)));
connect(session, SIGNAL(activityDetected(Terminal*)), m_window, SLOT(handleTerminalActivity(Terminal*)));
connect(session, SIGNAL(silenceDetected(Terminal*)), m_window, SLOT(handleTerminalSilence(Terminal*)));
connect(session, SIGNAL(destroyed(int)), this, SLOT(cleanup(int)));
m_sessions.insert(session->id(), session);
QString tab_label = QString("Shell (") + QString::number(session->id(), 16) + ")";
addTab(session->widget(), tab_label);
emit sessionAdded(session->id());
raiseSession(session->id());
return session->id();
}
There's a QTabBar::tabBarDoubleClicked signal, you just need to connect it to a slot to detect a double click. Also you'll need some widget to actually edit the tab's text. If you want it "out of place" (say, you open a dialog) then it should be enough to do something like:
connect(tabWidget->tabBar(), &QTabBar::tabBarDoubleClicked,
this, MyWidget::editTabBarLabel);
void MyWidget::editTabBarLabel(int tabIndex)
{
if (tabIndex < 0)
return;
// open dialog asking for the new label,
// f.i. via QInputDialog::getText
// set the new label bakc
}
If instead you want some in-place modification you'll need to more or less heavily modify QTabBar to do so.
The simplest option would be opening a QLineEdit on the right tab. To get the geometry of a tab via QTabBar:.tabrect, so that you can place the line edit in the same geometry. You'll very likely fall short on that path (see below) and you'll need to subclass QTabBar and use initStyleOption for the given tab, then set the lineedit's geometry to the right subrect (for instance, do not cover the "side widgets" of a tab).
Random pseudo braindumped code:
void MyTabBar::editTabBarLabel(int tabIndex)
{
if (tabIndex < 0)
return;
if (!m_lineEdit) {
m_lineEdit = new QLineEdit(this);
// once done, commit the change, or abort it, anyhow
// destroy/hide (?) the line edit
connect(m_lineEdit, &QLineEdit::editingFinished,
this, &MyTabBar::renameLabel);
} else {
// we're actually editing something else, what to do?
// commit the other change and start editing here?
}
m_editedTabIndex = tabIndex; // remember which one we're editing
m_lineEdit->setText(tabText(tabIndex));
// not "entirely" accurate, you need better subrect control here,
// cf. QStyle and https://doc.qt.io/qt-5/style-reference.html#widget-walkthrough
// that's why this should really be a QTabBar subclass, because
// you'll need to invoke initStyleOption and then fetch the subrects from the style
m_lineEdit->setGeometry(tabRect(tabIndex));
m_lineEdit->show();
}
// also track resize of the tabbar, relayout, tab reorder, tab insertion and removal, etc.
// move the QLineEdit accordingly
I'm a beginner in Flex so there must be more elegant way of doing this.
//move effect
private var m:Move = new Move();
//this function creates labels with some text and starts move effect on them
public function moveText(i:int):void {
var myLabel:Label = new Label();
myLabel.text = "some text";
m.target = myLabel;
...
m.play();
}
Method moveText is called in a loop so I guess that labels don't get "garbage collected".
What I want to do is to remove Labels created in moveText method after play animation ends.
Another way of doing this is maybe creating some kind of "pool" of labels which I would use to move arround text. I don't know how would I return labels in to "pool".
The question is how to do something after effect animation ends?
You can listen to the EffectEnd event.
Check out here
Look at the effectEnd event in the Effect class. You can put a handler in there that does your garbage collection.
I would like to create some text on the stage that does not respond to mouse activity. I've found that after adding a piece of text to a class I am using to draw, it covers up some of the mousing area of my class and disables the user from being able to roll over the other graphical elements...
Is there something like:
var t:TextField = new TextField();
t.text = "hello";
t.active = false; //i know that this is wrong, but I haven't found an equivalent method
Thanks,
jml
Use this
t.selectable = false;
Is there anyway I can effectively call the equiv. of setText on a Flex Graphics object ?
Specifically I'm using a custom cell renderer to display data in a datagrid. The renderer uses the Graphics object to set the background colour of only a portion of the cell (say the left half) based upon the underlying data. I would like to be able to have text over only that portion of the cell which has the background colour (eg centred within the left half).
I know all the widths (of both the cell itself and the graphics object) but I don't know how I can set text (centred) over the graphics object.
Anyone got any ideas pls?
Tks vm
Here's a solution that avoids adding UI components:
private function WriteText(text:String, rect:Rectangle):void
{
var uit:UITextField = new UITextField();
uit.text = text;
uit.width = rect.width;
var textBitmapData:BitmapData = ImageSnapshot.captureBitmapData(uit);
var matrix:Matrix = new Matrix();
var x:int = rect.x;
var y:int = rect.y;
matrix.tx = x;
matrix.ty = y;
graphics.beginBitmapFill(textBitmapData,matrix,false);
graphics.drawRect(x,y,uit.measuredWidth,uit.measuredHeight);
graphics.endFill();
}
The idea is to use the UITextField to create a bitmap, that can be used with the graphics object to fill a rectangle.
This is based on a blog post by Olga Korokhina at Adobe Developer Connection.
The short answer is that you can't draw text programmatically with a Graphics object. What you'll need to do is create one of the Text-like classes (e.g. Label, Text, etc.) and position that appropriately within your cell renderer.
Assuming that you're doing your custom painting in updateDisplayList, you'd want to do something like the following:
override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number ):void
{
super.updateDisplayList( unscaledWidth, unscaledHeight );
// perform all your custom painting
var label:Label = new Label();
label.text = "Some text";
label.width = widthOfCustomPainting;
// can also set x- and y-coordinates of label too
label.setStyle( "textAlign", "center" );
this.addChild( label );
}
This will need some tweaking based on how your item renderer is set up, but it should pretty much be what you need.
Note that my code above does not use best practices for custom item renderers. It would be worthwhile to take a look at this excellent blog post which describes how to properly create item renderers.
Polygonal labs comes up with a solution that convert the font to vector curves so that you can draw the text as graphics. See it here. The code has not been published, but you can see some similar projects in the comments.
But you will need to do it in AS instead of MXML or you write you own class for that.
using textformat for uit's defaulttextformat is the solution of my problem...