smalltalk Button event handling - oop

I am new with Squeak Smalltalk. How I can catch a button click event and execute some code when the button is clicked.
I tried this code but it doesn't work!
I created a new Button Class:
SimpleButtonMorph subclass: #ButtonTest
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'test'
Inside this class I write this method:
handleMouseDown: event
^ true.
I want to use the button inside another Morph, so i created new Morph class:
RectangleMorph subclass: #RectangleMorphTest
instanceVariableNames: 'textField button stringLabel mouseAction'
classVariableNames: ''
poolDictionaries: ''
category: 'test'
and inside Initialize method i compose buttonMorph inside RectangleMorph, The initialize method for rectangleMorph:
initialize
super initialize.
self bounds: ((0#0) extent: (400#400)).
self color: Color gray.
textField := TextFieldMorph new.
textField color: Color lightYellow.
textField contents: 'text'.
textField bounds: ((25#25) extent: (300#75)).
button := ButtonTest new.
button borderWidth: 2.
button bounds: ((150#150) extent: (200#200)).
button label: 'print text'.
button target: button.
button mouseDownOn: #yellowButtonPressed event: [Transcript show: 'hello'].
stringLabel := StringMorph new contents: 'This is a string'.
stringLabel bounds: ((150#180) extent: (200#200)).
self addMorph: textField.
self addMorph: button.
self addMorph: stringLabel.
Question
I tried to handle a Button event inside RectangleMorph, but it didn't work. So how I can handle a Button click event inside the RectangleMorph?

Searching for SimpleButtonMorph on the http://wiki.squeak.org/squeak gives you a number of hits.
Some examples how to use the button class here
You basically have to define a target for the button and an action selector. The target may be a block of code and the action selector the method #value you sent to the block.
So you have
button target: [Transcript show: 'hello'].
And then
button actionSelector: #value.
See also
http://wiki.squeak.org/squeak/2284 Morph mouse up action
http://wiki.squeak.org/squeak/57

I add a simple working snippet that maybe be useful for beginners. Tested in Squeak 5.2.
SimpleButtonMorph new
target: [Transcript show: 'Hello World !'; cr ];
label: 'Print something classic ...';
actionSelector: #value;
openInWorld.

Related

Spec - I want to replace the first presenter in a SpPanedLayout

Is that possible without needed to rebuild the whole presenter?
I am trying this code, but it does not work correctly:
self layout remove: (self layout children first).
self layout add: aNewPresenter.
It actually removes the presenter, but the new presenter is not placed at the first place but at the end.
In Spec2, all layouts are dynamic (meaning they can be modified at runtime), but each layout has different API and hence they need to be modified in different ways. In particular, SpPanedLayout has just two children: first and second (they can be displayed vertically -top to bottom- or horizontally -left to right-).
This means that unlike SpBoxLayout, in SpPanedLayout the use of #add: and #remove: messages are not necesary and will not always produce the desired result, and since #add: will try to add the presenter at the end of the list, in case it succeeds it will always be the second.
Instead, you can just set the children, and you will be effectively replace the presenter at the place you want.
Assuming you have the gtk backend installed, this code:
presenter := SpPresenter new.
presenter application: (SpApplication new useBackend: #Gtk).
presenter layout: (SpPanedLayout newHorizontal
first: (presenter newLabel label: 'I will replace this');
second: (presenter newLabel label: 'Powered by Pharo');
yourself).
presenter openWithSpec title: 'Example replace paned presenter'.
presenter layout
first: (presenter newImage image: (presenter application iconNamed: #pharoBig)).
Will replace the label "I will replace this" with the pharo logo in runtime.
And it will produce this output:

Qml button fix size

I have made list whose delegate is RowLayout consist of Button. The list takes data from cpp.
My problem is the button variable width. The button side changed based on data. I want to keep fix button side and wrap text
To give your Button a fixed width, just set the property with the same name to a fixed value.
The Button has a contentItem that is a Text. You can change the wrapMode there to Text.WordWrap
As the contentItem is of type Item you can't set the wrapMode like this:
Button {
width: 100
text: 'Very very long button description.'
contentItem.wrapMode: Text.WordWrap // Won't work
}
Instead you might use Component.onCompleted like this:
Button {
width: 100
text: 'Very very long button description.'
Component.onCompleted: contentItem.wrapMode = Text.WordWrap
}

Limiting context menu

In Dolphin Smalltalk I've set a context menu on a treeview, but this menu appears whenever I right click everywere on the tree, even if I click on an empty space.
How can I limit the popup to only existing rows of the tree ?
Best regards.
Maurizio.
Finally I've found it.
For those interested :
In the CreateSchematicWiring method :
treePresenter
when: #rightButtonPressed:
send: #onRightButtonPressed:
to: self
and this is the "onRightButtonPressed" method:
onRightButtonPressed: aMouseEvent
| treeView item |
treeView := treePresenter view.
item := treeView itemFromPoint: aMouseEvent position.
item
ifNil: [treeView contextMenu: nil]
ifNotNil: [:elem | treeView contextMenu: (treeView objectFromHandle: elem) getMenu]
where the getMenu method returns a menu depending on the kind of object on which I've clicked.

How to open dialog or popup when clicking on a cell in Dojo Dgrid

I want to open a dialog box when clicking on a cell.I am using dgrid/editor.
editor({field: "column1",label: "col1",editor: "text",editOn: "click"})
I am getting text box when using the above code.I want a dialog box.Please tell me how to get a dialog box.I am using OndemandGrid with JSONReststore to display the grid.
You don't need use editor to trigger a dialog, use click event on a cell is ok:
var grid = new declare([OnDemandGrid,Keyboard, Selection])({
store: Observable(new Memory({data: []}))
}, yourGridConatiner);
grid.on(".dgrid-content .dgrid-cell:click", function (evt) {
var cell = grid.cell(evt);
var data = cell.row.data;
/* your dialog creation at here, for example like below */
var dlg = new Dialog({
title: "Dialog",
className:"dialogclass",
content: dlgDiv //you need create this div using dojo.create or put-selector
});
dlg.show();
});
If you want show a pointer while mouse over that cell, you can style it at renderCell method with "cursor:pointer"
From the wiki:
editor - The type of component to use for editors in this column; either a string specifying a type of standard HTML input to create, or a Dijit widget constructor to instantiate.
You could provide (to editor) a button that pops up a dialog when clicked, but that would probably mean two clicks to edit a cell: one to focus or enter edit mode or otherwise get the button to appear and one to actually click the button.
You could also not bother with the editor plugin and attach a click event handler to the cell and pop up a dialog from there. You would have to manually save the changes back to your store if you went that route.
If I understand you right - you could try something like this:
function cellFormatter1(value) {
//output html-code to open your popup - ie. using value (of cell)
}
......
{field: "column1",label: "col1", formatter: cellFormatter1 }

Always show dojo tooltip

I have the following code for adding tooltip for onclick of a span id as shown below:
new dijit.Tooltip({
connectId: ['gridEditHelp'],
label: 'Double click on an item in the below table to perform inline editing of attributes',
position: ['above']
});
The problem is that I want the tooltip to be visible always on the web page.
Any ideas or existing API available for the same?
Use TooltipDialog instead - or else you will have to mess with the _MasterTooltip manager (there's more or less only one global, reusable tooltip). Then call dijit.popup.open - and never call .close
dijit.popup.open({
popup: new TooltipDialog({
id: 'myTooltipDialog',
style: "width: 300px;",
content: "<p>I have a mouse leave event handler that will close the dialog."
});,
around: dojo.byId('thenode')
});