Scala: Button in Table Cell does not "fire" Action - scala

I've got a little Problem: I want to have Buttons in some of the cells of my Table. As rendering component I return a Button with the following code: (theres application specific and debugging code in this example but you'll get the picture)
class LivingTreeButton(lt:LivingTree[_], client:TableBehaviourClient) extends Button(Action("xx") {
println("fire!")
lt.expanded = !lt.expanded
client.refresh
}){
println("I print therefore I am")
}
now when I scroll to one of the Buttons in the Table I see the "I print therefore I am" printouts and I do see the buttons with the "xx" text. But when I press one of the buttons nothing happens and I don't even see the "fire!" printouts.
It doesn't work neither, when I define the Action in the Buttons body instead of the constructor.
As further background info:
I'm not blocking the tables Events or anything. I only have a to listeners set up in JTable
peer.getColumnModel().addColumnModelListener(behaviourWorker)
peer.getTableHeader().addMouseListener(behaviourWorker)
and only temporarily block one of my own events in the Tables subclass:
listenTo(this.selection)
reactions += {
case e#TableRowsSelected(_,_,true) => if(!blockSelectionEvents) publish(PimpedTableSelectionEvent(this))
}
has any of you ever struggled with the same problem or has any idea what might be going wrong. After 2 hours od resultless debugging I would be thankfull for ANY hint.

Guess I got it. Didn't know that I have to add a TableCellEditor to catch the events. Doesn't really work yet but I'm sure that's it.

Related

Unity/NGUI Updating List at runtime

I was wondering if someone could explain to me how I update a list at runtime in Unity?
For example I have a spell book, which has 3 spells in it, when I drag them to my action bar they get re-parented to it, what I'm trying to do is get a list of each child under the actionbar transform,
My problem is where to actually do something like this if I try something like below in the update, it adds whatever's there many times, which I can understand since update runs every frame..
list = actionbarui.GetComponent(UIGrid).GetChildList();
for(var i =0;i < list.size; i++)
{
buttonList.Add(list[i].gameObject);
}
If I add a callback to the buttons so that whenever they're drag and dropped it runs the above code and add thing's additively, as in, if you drag just one "spell" on it will loop through once, which is fine, but as soon as you add another it loops through three times, that is, it already has one it then adds the same one again PLUS the new button that's just been dragged on for a total of 3.
I've tried changing the code to
list = actionbarui.GetComponent(UIGrid).GetChildList();
for each(var child : Transform in list.GetEnumerator())
{
buttonList.Add(child.gameObject);
}
But this simple doesn't add anything, I am unsure how to go about keep the lists update as they are dragged off and on, could anyone please explain how this is achieved?
Please ignore the second "list" code, it's implementing "BetterLists" as apart of NGUI, so doesn't follow standard list methods.
Thank you for reading
If I add a callback to the buttons so that whenever they're drag and dropped it runs the above code and add thing's additively, as in, if you drag just one "spell" on it will loop through once, which is fine, but as soon as you add another it loops through three times, that is, it already has one it then adds the same one again PLUS the new button that's just been dragged on for a total of 3.
That is the expected result here. You are running through the list of children and adding them to your buttonlist, so first time there is only one item to add, then when you add another child there are two items to add, thus resulting in three items.
Either don't have a for loop and do:
buttonList.Add(the_GameObject_that_was_just_added_to_the_bar);
Or clear your buttonList before the for loop:
list = actionbarui.GetComponent(UIGrid).GetChildList();
buttonList.Clear();
for(var i =0;i < list.size; i++)
{
buttonList.Add(list[i].gameObject);
}
Alternatively to Dover8's response, you can first check if the buttonList already contains a reference to the child to be added. If it does, continue. Otherwise add the new child.
However, given the expense of doing the checks, and since you are already looping through the list already, I'd recommend that you follow his suggestion to clear the list before running the loop. It will probably give you the best performance out of these examples.
If there's a reason you can't or shouldn't clear the buttonList, and you still need to run through it, I'd recommend my suggestion. It really depends on which implementation works best for what you are trying to do. The point is that there are several ways to do this, and they have different performance profiles you need to consider.

Headers disappear when after overriding TableView.Scrolled

I have been in a pickle with this problem for a while now. When I try to manually handle how my table behaves while scrolling, everything works fine, except all my section headers disappear. What I tried to do was make the scroll view expand after I have scrolled for X number of points. The headers are not visible from the very start, but when I comment the override out, my headers are there as normal. Does anyone have any idea how I could fix this and make my section headers appear ?
A sample of my code is as follows :
dialog.TableView.Scrolled += delegate {
if (dialog.TableView.ContentOffset.Y > this.View.Frame.Height)
{
dialogView.Frame = new RectangleF(0,0,320,this.View.Frame.Height);
}
};
If you subscribe to Scrolled on a UITableView, it will likely overwrite the underlying UITableViewSource that tells it how many sections/rows there are, etc.
It looks like you are using MonoTouch.Dialog, is the table simple enough where you could use a normal UITableView for this case? There is a Scrolled method you can override on UITableViewSourceinstead of using the C# event.

Perl HList: Change -background for individual items

I'm trying to alert the user that some data has been changed and needs to be saved. The data is displayed in Perl's Tk::HList box. I was hoping I could do:
if ($new_item) {
$HList->add($stock_no,-background=>"red");
}
or even:
if ($new_item) {
$HList->itemCreate($stock_no,0,-text=>$stock_no,-background=>"red");
}
but both throw
Tk::Error: Bad option `-background'
I've seen the idea to use ItemStyle but there's no clear answer if that works or not or if it's the best (and only) solution. Is there another way to highlight certain rows to alert the user?
It looks like it is the best way to change the background:
use Tk::ItemStyle;
my $alert = $mw->ItemStyle('text',-background=>"red");
$HList->itemCreate($stock_no,0,-style=>$alert);
I have to include that style to each item I add, there doesn't seem to be a way to do the whole row at once.

QCompleter and Tab key

I'm trying to make a Completion when pressing tab, you get the first completion of all possibilities.
But, in a QWidget-based main window, pressing tab will make that QLineEdit lost focus, and completion popup hides after that.
Is there a way to fix it ?
Have you tried to subclass QLineEdit and intercept the key press event?
Alternatively you could set up an event filter.
Whew. It took me some time to figure this out :) Multiple times I have tried to solve this problem, but always gave up. Now, I dug enough to find the answer.
OP, please pardon me, because the code here is Python, but should be understandable and work for C++ as well.
Basically, the problem I had was "how to select an entry in the QCompleter"; I didn't notice before, but the answer is in the popup() method. QCompleter works with a model and a view, which contains the things to show.
You can change the current row as you wish, then get the index of that row in the model, then select it in the pop-up.
In my code, I subclassed QLineEdit, created a tabPressed signal which is emitted every time Tab is pressed. Then, connected this signal to a method of the same class which does this:
get the current index;
select the index in the popup;
advance to the next row.
As implementation, this is very trivial, but for my current purpose this is enough. Here's the skeleton (just for the tab part, it's missing the model and everything else).
class MyLineEdit(QLineEdit):
tabPressed = pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
self._compl = QCompleter()
self.tabPressed.connect(self.next_completion)
def next_completion(self):
index = self._compl.currentIndex()
self._compl.popup().setCurrentIndex(index)
start = self._compl.currentRow()
if not self._compl.setCurrentRow(start + 1):
self._compl.setCurrentRow(0)
def event(self, event):
if event.type() == QEvent.KeyPress and event.key() == Qt.Key_Tab:
self.tabPressed.emit()
return True
return super().event(event)
You may need to adjust/fix few things, but this is the basic idea.
EDIT:
For details see
http://www.qtcentre.org/threads/23518-How-to-change-completion-rule-of-QCompleter
There's a little issue: when Return is pressed, the things don't work properly. Maybe you can find a solution to this problem in the link above, or in the referenced resources therein. I'll fix this in the next few days and update this answer.
There is probably a better solution but one that comes to mind is to change the focus policy for all other widgets on the form to something that doesn't include "tab" focus. The only options that don't use the tab key are Qt::ClickFocus and Qt::NoFocus.

Redrawing control behind composite with SWT.NO_BACKGROUND

Original goal:
I have a TreeMenu that i use to display my Menu.
In this tree, a user can select different items.
I would like to disable the tree, so that a user cannot select a new item after choosing the first.
The catch is, we cannot use setEnabled, because we are not allowed to use the greyed out look. The look/colors may not change.
Our proposed solution
Our first idea was to use a Composite with SWT.NO_BACKGROUND on top of the menu, to prevent any user interaction with the TreeMenu.
Code:
final Composite cover = new Composite(getPage().shell, SWT.NO_BACKGROUND);
cover.setLocation(getMenu().getLocation());
cover.setSize(getMenu().getSize());
cover.moveAbove(getMenu());
This has a problem with redrawing.
If the screen is covered by another screen and then brought back to front, the Cover Composite is filled with fragments of the previous overlapping window.
Our idea was to manually redraw the menu:
cover.moveBelow(getMenu());
getMenu().update();
cover.moveAbove(getMenu());
We placed the code inside the paintEventListener.
But this caused an infinite loop and did not solve the problem.
Questions
Does anyone have an idea how we can achive our orignial goal?
Does anyone know how we can make our proposed solution work?
Look at SWT-Snippet80. It shows how to prevent selections. A solution to your problem would be adding a listener like this to your tree:
tree.addListener(SWT.Selection, new Listener() {
TreeItem[] oldSelection = null;
public void handleEvent( Event e ) {
Tree tree = (Tree)(e.widget);
TreeItem[] selection = tree.getSelection();
if ( oldSelection != null )
tree.setSelection(oldSelection);
else
oldSelection = selection;
}
});
I wouldn't recommend trying to implement your workaround. I believe that placing transparent controls on top of each other is unsupported in SWT - I think I read a comment from Steve Northover on this subject once. Even if you made it work for some OS, it probably won't work in another - it's too much of a hack.
A solution that is supported by SWT, is having transparent windows on top of each other. But that is also really hard to implement (resizing, moving, always on top, redraw artifacts) and probably as big a hack as the other workaround. Go for the listener.