I want to show a popup menu if 'right click' in a row from GtkTreeView.
It is possible that the popup menu shows up only if 'right click' in first column (or specificate column)?
I have use code but this sown up menu for entire row.
gboolean
on_tree_view_button_pressed(GtkWidget *treeview, GdkEventButton *event, gpointer data)
{
if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
GtkTreePath *path;
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeview),
event->x, event->y,
&path, NULL, NULL, NULL)) {
gtk_tree_selection_unselect_all(selection);
gtk_tree_selection_select_path(selection, path);
gtk_tree_path_free(path);
}
do_popup_menu(treeview, event, data);
return TRUE;
}
return FALSE;
}
I have GtkTreeView with 3 columns and I want to show up menu only for first column
You are already calling gtk_tree_view_get_path_at_pos. This function can also obtain the treeview column under the mouse. Instead of passing NULL for the column argument, make sure to get the column and compare it to your desired column:
if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
GtkTreePath *path;
GtkTreeViewColumn *column;
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeview),
event->x, event->y,
&path, &column, NULL, NULL))
// if we can't find path at pos, we surely don't
// want to pop up the menu
return FALSE;
if (column != gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 0)) {
// wrong column, don't bother
gtk_tree_path_free(path);
return FALSE;
}
gtk_tree_selection_unselect_all(selection);
gtk_tree_selection_select_path(selection, path);
gtk_tree_path_free(path);
do_popup_menu(treeview, event, data);
return TRUE;
}
Related
I need to disable 1(or 2) dropdown option from a dropdown menu in Unity.
The dropdown menu should not be repopulated.
There should not be any deletion/deactivated options from the dropdown menu
Anyone have any idea how to do this. ?
Similar to this answer but a slightly different approach.
The other answer uses a hardcoded toggle.name == "Item 1: Option B" to compare the buttons. I'd rather use a central and index-based system:
Put this component on the DropDown
[RequireComponent(typeof(Dropdown))]
[DisallowMultipleComponent]
public class DropDownController : MonoBehaviour, IPointerClickHandler
{
[Tooltip("Indexes that should be ignored. Indexes are 0 based.")]
public List<int> indexesToDisable = new List<int>();
private Dropdown _dropdown;
private void Awake()
{
_dropdown = GetComponent<Dropdown>();
}
public void OnPointerClick(PointerEventData eventData)
{
var dropDownList = GetComponentInChildren<Canvas>();
if (!dropDownList) return;
// If the dropdown was opened find the options toggles
var toogles = dropDownList.GetComponentsInChildren<Toggle>(true);
// the first item will always be a template item from the dropdown we have to ignore
// so we start at one and all options indexes have to be 1 based
for (var i = 1; i < toogles.Length; i++)
{
// disable buttons if their 0-based index is in indexesToDisable
// the first item will always be a template item from the dropdown
// so in order to still have 0 based indexes for the options here we use i-1
toogles[i].interactable = !indexesToDisable.Contains(i - 1);
}
}
// Anytime change a value by index
public void EnableOption(int index, bool enable)
{
if (index < 1 || index > _dropdown.options.Count)
{
Debug.LogWarning("Index out of range -> ignored!", this);
return;
}
if (enable)
{
// remove index from disabled list
if (indexesToDisable.Contains(index)) indexesToDisable.Remove(index);
}
else
{
// add index to disabled list
if (!indexesToDisable.Contains(index)) indexesToDisable.Add(index);
}
var dropDownList = GetComponentInChildren<Canvas>();
// If this returns null than the Dropdown was closed
if (!dropDownList) return;
// If the dropdown was opened find the options toggles
var toogles = dropDownList.GetComponentsInChildren<Toggle>(true);
toogles[index].interactable = enable;
}
// Anytime change a value by string label
public void EnableOption(string label, bool enable)
{
var index = _dropdown.options.FindIndex(o => string.Equals(o.text, label));
// We need a 1-based index
EnableOption(index + 1, enable);
}
}
Configure in the Inspector
or via scripts e.g.
dropDownReference.GetComponent<DropDownController>().EnableOption("Option B", false);
You can achieve this using the Toggle component from DropDown->Template->ViewPort->Content->Item.
This script is creating items every time DropDown menu is selected. You can just access Toogle and disable interactable field like this:
void Start ()
{
//This script should be attached to Item
Toggle toggle = gameObject.GetComponent<Toggle>();
Debug.Log(toggle);
if (toggle != null && toggle.name == "Item 1: Option B")
{
toggle.interactable = false;
}
}
You can also see a DropDown list is created every time arrow on DrowDown is clicked and destroyed when menu is closed.
I need help debugging the follow issue:
When I click on a Vaadin Grid with 3 rows, it ignores the click on any but the last row and always selects the 3rd row.
Code is as follows:
// declare Grid objects
public final Grid<SoapKPIContainer> soapKPIOverviewGridDisplay;
..
public SoapKPIOverviewView(SoapKPIRepository soapKPIRepository, Navigator navigator,
BpspSoapCheckCommunications bpspSoapCheckCommunications,
UIMessageByLocaleService messageByLocaleService) {
..
this.soapKPIOverviewGridDisplay = new Grid<>(SoapKPIContainer.class);
this.soapKPIOverviewGridDisplay.setColumns();
Grid.Column<SoapKPIContainer, ?> lastAlarmStatusIconColumn = this.soapKPIOverviewGridDisplay.addColumn("lastAlarmStatusIcon", new ImageRenderer<>());
lastAlarmStatusIconColumn.setSortable(false);
lastAlarmStatusIconColumn.setResizable(false);
lastAlarmStatusIconColumn.setWidth(80.0f);
lastAlarmStatusIconColumn.setCaption(messageByLocaleService.getMessage("label.lastalarmstatus"));
Grid.Column<SoapKPIContainer, ?> activationIconColumn = this.soapKPIOverviewGridDisplay.addColumn("activationIcon", new ImageRenderer<>());
activationIconColumn.setSortable(false);
activationIconColumn.setResizable(false);
this.soapKPIOverviewGridDisplay.getDefaultHeaderRow().getCell("lastAlarmStatusIcon").setHtml(messageByLocaleService.getMessage("label.lastalarmstatus"));
this.soapKPIOverviewGridDisplay.getDefaultHeaderRow().getCell("activationIcon").setHtml(messageByLocaleService.getMessage("label.activationicon"));
this.soapKPIOverviewGridDisplay.addColumn(SoapKPIContainer::getKpiName).
setCaption(messageByLocaleService.getMessage("header.kpiName"));
..
this.setSizeFull();
this.soapKPIOverviewGridDisplay.setSizeFull();
this.soapKPIOverviewGridDisplay.setHeight(400, Unit.PIXELS);
this.soapKPIService = new SoapKPIService(soapKPIRepository);
this.soapKPIOverviewGridDisplay.setItems( soapKPIService.toContainer( soapKPIService.findAllSoapKPI() ) );
..
// adding Listener for the Grid to enable for the user to select single KPIs
soapKPIOverviewGridDisplay.setSelectionMode(SelectionMode.SINGLE);
soapKPIOverviewGridDisplay.asSingleSelect().addValueChangeListener(e -> {
log.debug("asSingleSelect().addValueChangeListener " + e.getValue());
if ( e.getValue() != null) {
log.debug("asSingleSelect().addValueChangeListener findSoapKPIById #" + e.getValue().getKpiId());
testKPIDefView.setEnabled(true);
soapKPI = soapKPIService.findSoapKPIById( e.getValue().getKpiId() );
changeEnabled.setVisible(true);
if( soapKPI.getEnabled() == 1)
changeEnabled.setCaption(messageByLocaleService.getMessage("button.disable"));
else
changeEnabled.setCaption(messageByLocaleService.getMessage("button.enable"));
}
else {
testKPIDefView.setEnabled(false);
changeEnabled.setVisible(false);
soapKPI = null;
}
});
..
soapKPIOverviewLayout.addComponent(soapKPIOverviewGridDisplay);
I'm still not sure what line in the code cause it to break, but I found that overriding the equals method of the row object makes the problem go away:
#Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof SoapKPIContainer)) {
return false;
}
SoapKPIContainer container = (SoapKPIContainer) o;
return this.getKpiId() == container.getKpiId();
}
i am trying to put elements on a listview and treeview with javafx, but both controls wont refresh theyre content. i am using an obvservable list to control the items and every time i delete one item, the listview or treeview removes it from the datasource. but the view is not updating. i am still seeing all the items. the only difference is, the removed item can not be selected any more. for example link 2 shows the collaped item list. image 1 shows the items before they are collaped. the items are collapsed but the old entry is still visible. does anybody know a solution for this problem. thank you all for helping me
link 1: treeview is not collapsed
link 2: treeview is collapsed but not updating old view
this is the custom cell factory i use to display a listview:
public ListCell<T> call(final ListView<T> param) {
ListCell<T> cell = new ListCell<T>(){
#Override
protected void updateItem(final T persistentObject, final boolean empty) {
super.updateItem(persistentObject, empty);
if(persistentObject instanceof POProcessStep){
POProcessStep poProcessStep = (POProcessStep) persistentObject;
if (persistentObject != null) {
super.setText(poProcessStep.getId() + " - " + poProcessStep.getTitle());
}
}else if(persistentObject instanceof POProcess){
POProcess poProcess = (POProcess) persistentObject;
if (persistentObject != null) {
super.setText(poProcess.getId() + " - " + poProcess.getTitle());
}
}else if(persistentObject instanceof POCategory){
POCategory poCategory = (POCategory) persistentObject;
if(persistentObject != null){
super.setText(poCategory.getId() + " - " + poCategory.getTitle());
}
}else if(persistentObject instanceof String){
if(persistentObject != null){
super.setText(String.valueOf(persistentObject));
}
}
super.setGraphic(null);
}
};
return cell;
}
Your cell factory's updateItem(...) needs to handle the case where the cell is empty. This will be exactly the scenario when an item is removed (or becomes empty because a node in the TreeView was collapsed) and the cell that previously showed an item is reused as an empty cell:
public ListCell<T> call(final ListView<T> param) {
ListCell<T> cell = new ListCell<T>(){
#Override
protected void updateItem(final T persistentObject, final boolean empty) {
super.updateItem(persistentObject, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
// ... rest of your code.
}
}
}
return cell ;
}
void CatchSelection(QModelIndex item)
{
if(item.row() == -1)
{
return;
}
if (item.parent().row() != -1)
{
QModelIndex idx = model()->index(item.row(), 1, item.parent());
__int64 value = model()->data(idx).toLongLong();
}
}
The above code doesn't work. I'm trying to get data out of a Qt 5.1 QTreeView when the user clicks on an item. Then I'm trying to select the 2nd column of that item (it has a number I need).
What am I missing?
When using TableBuilder to create rows and sub rows, selection model isn't working as expected.
When clicking on a subrow's checkbox the row isn't been selected, however, the parent row become selected instead.
I tried to overload onBrowserEvent of the CheckboxCell in order to manually handle the selection but it seems that the DataGrid itself fires the selection event when pressing the checkboxcell.
In case where rows and subrows are from the same type, how can I add selection model that supports both rows and subrows?
#Override
public void onBrowserEvent(Context context, Element elem, final T object,
NativeEvent event) {
// The provided row is always the root row, so we need to find the
// correct one when a sub row was edited
actualIndex = context.getSubIndex();
actualObject = object;
if (0 != context.getSubIndex() && object instanceof RowDTO) {
actualIndex = context.getSubIndex();
actualObject = (T) ((RowDTO) object).getChild(actualIndex - 1);
context = new Context(context.getIndex(), context.getColumn(),
actualObject, actualIndex);
}
ValueUpdater<C> valueUpdater = (getFieldUpdater() == null) ? null
: new ValueUpdater<C>() {
#Override
public void update(C value) {
getFieldUpdater().update(actualIndex, object, value);
}
};
getCell().onBrowserEvent(context, elem, getValue(actualObject), event,
valueUpdater);
}