Treegadget: Wie das Element bei Rechtsclick feststellen
Treegadget: Wie das Element bei Rechtsclick feststellen
Hallo Leute,
Neu im Forum und schon gleich meine 3. Frage heute...(das sind die gesammelten die mich schon eine weile quälen):
In einem Treegadget will ich mit LinksClick auf einen Eintrag etwas anzeigen. Ein darauffolgender Rechtsclick auf das Element soll dann ein PopupMenu anzeigen.
Gibt's eine Möglichkeit (ohne API) festzustellen auf welchem Element der Click stattgefunden hat ?
Das Problem ist das ich das Popup im Moment dort anzeige wo sich die Maus befindet und der Click kann auch im "Leerraum" unter dem letzten element stattgefunden haben.
Mit anderen Worten: Über #PB_EventType_Change + #PB_EventType_LeftClick krieg ich raus wenn ein element ausgewählt wurde. Wenn dann aber ein RechtsClick auf dem selben Element oder im Leerraum unter dem letzten Element RechtsgeClickt wird gib't kein #PB_EventType_Change und ich kann nicht entscheiden ob die Maus auf dem Element war oder nicht...
Danke!
Gruß
Onetime
Neu im Forum und schon gleich meine 3. Frage heute...(das sind die gesammelten die mich schon eine weile quälen):
In einem Treegadget will ich mit LinksClick auf einen Eintrag etwas anzeigen. Ein darauffolgender Rechtsclick auf das Element soll dann ein PopupMenu anzeigen.
Gibt's eine Möglichkeit (ohne API) festzustellen auf welchem Element der Click stattgefunden hat ?
Das Problem ist das ich das Popup im Moment dort anzeige wo sich die Maus befindet und der Click kann auch im "Leerraum" unter dem letzten element stattgefunden haben.
Mit anderen Worten: Über #PB_EventType_Change + #PB_EventType_LeftClick krieg ich raus wenn ein element ausgewählt wurde. Wenn dann aber ein RechtsClick auf dem selben Element oder im Leerraum unter dem letzten Element RechtsgeClickt wird gib't kein #PB_EventType_Change und ich kann nicht entscheiden ob die Maus auf dem Element war oder nicht...
Danke!
Gruß
Onetime
Re: Treegadget: Wie das Element bei Rechtsclick feststellen
Bin mir nicht sicher, ob du so was gemeint hast:
Code: Alles auswählen
OpenWindow (0, 0, 0, 200, 650, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
TreeGadget (0, 10, 10, 180, 630)
Procedure TreeRightClick ()
Debug GetGadgetState (0)
EndProcedure
BindGadgetEvent (0, @TreeRightClick(), #PB_EventType_RightClick)
For a = 0 To 10
AddGadgetItem (0, -1, "Normal Item " + Str(a), 0, 0)
AddGadgetItem (0, -1, "Node "+Str(a), 0, 0)
AddGadgetItem (0, -1, "Sub-Item 1", 0, 1)
AddGadgetItem (0, -1, "Sub-Item 2", 0, 1)
AddGadgetItem (0, -1, "Sub-Item 3", 0, 1)
AddGadgetItem (0, -1, "Sub-Item 4", 0, 1)
AddGadgetItem (0, -1, "File "+Str(a), 0, 0)
Next
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Re: Treegadget: Wie das Element bei Rechtsclick feststellen
Hallo Onetime,
ich kann dir leider auch nicht weiterhelfen, aber liege ich hiermit (das Problem) richtig ?
ich kann dir leider auch nicht weiterhelfen, aber liege ich hiermit (das Problem) richtig ?
Code: Alles auswählen
;Ich glaube hier sieht man das Problem! (Liege ich richtig ?)
;Ich habe aber leider auch keine API-freie Lösung/ platformübergreifende Lösung.
;Klickt man kein Element an wird beim Aktivieren ein Element selektiert. (Unerwünscht!)
;Klickt man in den Freiraum (ohne Eintrag) wird dort das Menü angezeigt (Wegen Mausposition) und es wird z.B. Eintrag 0 ausgewählt. (Unerwünscht!)
Structure Ast
x.i
y.i
w.i
h.i
EndStructure
Structure MPos
x.d
y.d
EndStructure
Global WinMaus.MPos
Global NewList BaumAst.Ast()
Global TestFenster, BaumElement, PopMenu
Global Quit.b = #False
Global KlickElement = -1
Procedure.b OverGadget(*MausPos.MPos, Element)
If ((*MausPos\x >= GadgetX(Element)) And (*MausPos\x <= (GadgetX(Element) + GadgetWidth(Element))) And (*MausPos\y >= GadgetY(Element)) And (*MausPos\y <= GadgetY(Element) + GadgetHeight(Element)))
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
TestFenster = OpenWindow(#PB_Any, 0, 0, 800, 600, "TestFenster", #PB_Window_SystemMenu)
If IsWindow(TestFenster)
BaumElement = TreeGadget(#PB_Any, 10, 10, 780, 580)
For i = 0 To 5
AddGadgetItem(BaumElement, i, "Eintrag: "+Str(i))
AddElement(BaumAst()) ;Mit diesen Werten könnte man rechnen. (Man müsste Sie nur ermittelt bekommen.)
BaumAst()\x = 0 ;GetItemPosX(i)?
BaumAst()\y = 0 ;GetItemPosY(i)?
BaumAst()\w = 0 ;GetItemWidth(i)?
BaumAst()\h = 0 ;GetItemHeight(i)?
Next i
If CreatePopupMenu(PopMenu)
MenuItem(1, "Menü-Eintrag 1")
MenuItem(2, "Menü-Eintrag 2")
MenuItem(3, "Menü-Eintrag 3")
EndIf
Repeat
event = WindowEvent()
Select event
Case #PB_Event_CloseWindow
Quit = #True
Case #PB_Event_Menu
Select EventMenu()
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case BaumElement
If EventType() = #PB_EventType_Change
KlickElement = GetGadgetState(BaumElement)
EndIf
If EventType() = #PB_EventType_LeftClick
Debug "Linksklick auf: "+Str(KlickElement)
ElseIf EventType() = #PB_EventType_RightClick
DisplayPopupMenu(PopMenu, WindowID(TestFenster))
Debug "Rechtsklick auf: "+Str(KlickElement)
EndIf
EndSelect
EndSelect
Until Quit = #True
EndIf
End
Zuletzt geändert von ccode_new am 24.11.2018 20:14, insgesamt 1-mal geändert.
Betriebssysteme: div. Windows, Linux, Unix - Systeme
no Keyboard, press any key
no mouse, you need a cat
no Keyboard, press any key
no mouse, you need a cat
Re: Treegadget: Wie das Element bei Rechtsclick feststellen
Vielen Dank schon mal für die Mühe.
Josh + ccode_new,
genau das Problem. Wenn ich in dem Beispiel von ccode_new einen RechtsClick in den leeren Bereich unter Eintrag 5 mache kommt dort das Popupmenü (und es wird behauptet das ich einen Eintrag in der Liste geClickt habe was ja nicht passiert ist .
Sollte ja nur auf dem Element selber Sinn machen .
Josh + ccode_new,
genau das Problem. Wenn ich in dem Beispiel von ccode_new einen RechtsClick in den leeren Bereich unter Eintrag 5 mache kommt dort das Popupmenü (und es wird behauptet das ich einen Eintrag in der Liste geClickt habe was ja nicht passiert ist .
Sollte ja nur auf dem Element selber Sinn machen .
Re: Treegadget: Wie das Element bei Rechtsclick feststellen
Hallo!
Kann das jemand für Windows anpassen ?
GTK3-Linux-Version:
Kann das jemand für Windows anpassen ?
GTK3-Linux-Version:
Code: Alles auswählen
ImportC ""
gtk_widget_style_get(*Widget.GtkWidget, PropertyName.P-UTF8, *Value, Null)
EndImport
Procedure.i GetRowHeight(GadgetID.i)
Protected *Column.GtkTreeViewColumn
Protected RowHeight.I
Protected VerticalSeparator.I
*Column = gtk_tree_view_get_column_(GadgetID(GadgetID), 0)
gtk_tree_view_column_cell_get_size_(*Column, 0, 0, 0, 0, @RowHeight)
gtk_widget_style_get(GadgetID(GadgetID), "vertical-separator", @VerticalSeparator, 0)
ProcedureReturn RowHeight + VerticalSeparator
EndProcedure
Procedure.i GetRowWidth(GadgetID.i)
Protected *Column.GtkTreeViewColumn
Protected RowWidth.I
Protected HorizontalSeparator.I
*Column = gtk_tree_view_get_column_(GadgetID(GadgetID), 0)
gtk_tree_view_column_cell_get_size_(*Column, 0, 0, 0, @RowWidth, 0)
gtk_widget_style_get(GadgetID(GadgetID), "horizontal-separator", @HorizontalSeparator, 0)
ProcedureReturn RowHeight + HorizontalSeparator
EndProcedure
Structure Ast
x.i
y.i
w.i
h.i
EndStructure
Structure MPos
x.d
y.d
EndStructure
Global WinMaus.MPos
Global NewList BaumAst.Ast()
Global TestFenster, BaumElement, PopMenu
Global Quit.b = #False, start.b = #True
Global KlickElement = -1, ypos = 0
Procedure.b OverGadget(*MausPos.MPos, Element)
If ((*MausPos\x >= GadgetX(Element)) And (*MausPos\x <= (GadgetX(Element) + GadgetWidth(Element))) And (*MausPos\y >= GadgetY(Element)) And (*MausPos\y <= GadgetY(Element) + GadgetHeight(Element)))
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
Procedure.b OverItem(*MausPos.MPos, Element, Eintrag)
SelectElement(BaumAst(), Eintrag)
If (*MausPos\y - GadgetY(Element)) < (BaumAst()\y + BaumAst()\h)
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
TestFenster = OpenWindow(#PB_Any, 0, 0, 800, 600, "TestFenster", #PB_Window_SystemMenu)
If IsWindow(TestFenster)
BaumElement = TreeGadget(#PB_Any, 10, 10, 780, 580)
For i = 0 To 5
AddGadgetItem(BaumElement, i, "Eintrag: "+Str(i))
Next i
If CreatePopupMenu(PopMenu)
MenuItem(1, "Menü-Eintrag 1")
MenuItem(2, "Menü-Eintrag 2")
MenuItem(3, "Menü-Eintrag 3")
EndIf
Repeat
event = WindowEvent()
WinMaus\x = WindowMouseX(TestFenster)
WinMaus\y = WindowMouseY(TestFenster)
Select event
Case #PB_Event_CloseWindow
Quit = #True
Case #PB_Event_Menu
Select EventMenu()
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case BaumElement
KlickElement = GetGadgetState(BaumElement)
If OverGadget(WinMaus, BaumElement) = #True And OverItem(WinMaus, BaumElement, KlickElement) = #True
If EventType() = #PB_EventType_LeftClick
Debug "Linksklick auf: "+Str(KlickElement)
ElseIf EventType() = #PB_EventType_RightClick
DisplayPopupMenu(PopMenu, WindowID(TestFenster))
Debug "Rechtsklick auf: "+Str(KlickElement)
EndIf
EndIf
EndSelect
EndSelect
If start = #True
While WindowEvent() : Wend
For i = 1 To CountGadgetItems(BaumElement)
AddElement(BaumAst())
BaumAst()\x = 0
BaumAst()\y = ypos
BaumAst()\w = GetRowWidth(BaumElement)
BaumAst()\h = GetRowHeight(BaumElement)
ypos = (GetRowHeight(BaumElement) * i)
Next i
; ForEach BaumAst()
; Debug BaumAst()\y + BaumAst()\h
; Next
start = #False
EndIf
Until Quit = #True
EndIf
End
Betriebssysteme: div. Windows, Linux, Unix - Systeme
no Keyboard, press any key
no mouse, you need a cat
no Keyboard, press any key
no mouse, you need a cat
Re: Treegadget: Wie das Element bei Rechtsclick feststellen
Der Grund ist, dass beim TreeGadget immer ein Element ausgewählt ist. Du kannst die Markierung nicht aufheben, indem du auf eine freie Stelle klickst. Ist genauso wie beim ComboBoxGadget. Sobald ein Eintrag aus der Liste ausgewählt wurde, ist immer ein Eintrag ausgewählt und du kannst nicht per Klick die Auswahl aufheben.Onetime hat geschrieben:Wenn ich in dem Beispiel von ccode_new einen RechtsClick in den leeren Bereich unter Eintrag 5 mache kommt dort das Popupmenü (und es wird behauptet das ich einen Eintrag in der Liste geClickt habe
Deshalb funktioniert die Klick-Auswertung auch korrekt.
Was man aber alternativ machen könnte, wäre eine Mauspositionsabfrage, ob der Cursor sich beim Klick innerhalb eines Eintrages befindet. Das kannst du mit GetCursorPos_() und MapWindowPoints_() erreichen. Im Forum gibt es genug Beispiele dafür.
Re: Treegadget: Wie das Element bei Rechtsclick feststellen
Danke für die Antworten.
- der Code von ccode_new sieht stark nach Windows API aus wenn's denn übersetzt werden kann. Wollte ich aber vermeiden. Trotzdem Danke!
- RSBasic: Ja im Treeview scheint das blöd gelöst zu sein. Ich hab einzelne Einträge kann aber nicht feststellen ob 'drauf geklickt worden ist. Das mit GetCursorPos_() und MapWindowPoints_() schau ich mir mal an. Evtl ist das ja eine Richtung....
Beste Grüsse
Onetime
- der Code von ccode_new sieht stark nach Windows API aus wenn's denn übersetzt werden kann. Wollte ich aber vermeiden. Trotzdem Danke!
- RSBasic: Ja im Treeview scheint das blöd gelöst zu sein. Ich hab einzelne Einträge kann aber nicht feststellen ob 'drauf geklickt worden ist. Das mit GetCursorPos_() und MapWindowPoints_() schau ich mir mal an. Evtl ist das ja eine Richtung....
Beste Grüsse
Onetime
Re: Treegadget: Wie das Element bei Rechtsclick feststellen
Windows + Linux (Gtk3)
Code: Alles auswählen
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
ImportC ""
gtk_widget_style_get(*Widget.GtkWidget, PropertyName.P-UTF8, *Value, Null)
EndImport
Procedure.i GetRowHeight(GadgetID.i)
Protected *Column.GtkTreeViewColumn
Protected RowHeight.I
Protected VerticalSeparator.I
*Column = gtk_tree_view_get_column_(GadgetID(GadgetID), 0)
gtk_tree_view_column_cell_get_size_(*Column, 0, 0, 0, 0, @RowHeight)
gtk_widget_style_get(GadgetID(GadgetID), "vertical-separator", @VerticalSeparator, 0)
ProcedureReturn RowHeight + VerticalSeparator
EndProcedure
CompilerElseIf #PB_Compiler_OS = #PB_OS_Windows
#TVM_GETITEMHEIGHT = $111C
Procedure.i GetRowHeight(GadgetID.i)
ProcedureReturn SendMessage_(GadgetID(GadgetID),#TVM_GETITEMHEIGHT,0,0)
EndProcedure
CompilerEndIf
Structure Ast
y.i
h.i
EndStructure
Structure MPos
x.i
y.i
EndStructure
Global WinMaus.MPos
Global NewList BaumAst.Ast()
Global TestFenster, BaumElement, PopMenu
Global Quit.b = #False, start.b = #True
Global KlickElement = -1, ypos = 0
Procedure.b OverGadget(*MausPos.MPos, Element)
If ((*MausPos\x >= GadgetX(Element)) And (*MausPos\x <= (GadgetX(Element) + GadgetWidth(Element))) And (*MausPos\y >= GadgetY(Element)) And (*MausPos\y <= GadgetY(Element) + GadgetHeight(Element)))
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
Procedure.b OverItem(*MausPos.MPos, Element, Eintrag)
SelectElement(BaumAst(), Eintrag) ;kleines Abfrage-Problem!
If (*MausPos\y - GadgetY(Element)) < (BaumAst()\y + BaumAst()\h) ;And (*MausPos\y - GadgetY(Element)) >= BaumAst()\y
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
TestFenster = OpenWindow(#PB_Any, 0, 0, 800, 600, "TestFenster", #PB_Window_SystemMenu)
If IsWindow(TestFenster)
BaumElement = TreeGadget(#PB_Any, 10, 10, 780, 580)
; For i = 0 To 5
; AddGadgetItem(BaumElement, i, "Eintrag: "+Str(i))
; Next i
For i = 1 To 2
AddGadgetItem (BaumElement, -1, "Item "+ Str(i), 0, 0)
AddGadgetItem(BaumElement, -1, "Item " + Str(i) + ".1", 0, 1)
AddGadgetItem(BaumElement, -1, "Item " + Str(i) + ".2", 0, 1)
AddGadgetItem(BaumElement, -1, "Item " + Str(i) + ".2.1", 0, 2)
AddGadgetItem(BaumElement, -1, "Item " + Str(i) + ".2.2", 0, 2)
AddGadgetItem(BaumElement, -1, "Item " + Str(i) + ".3", 0, 1)
Next i
If CreatePopupMenu(PopMenu)
MenuItem(1, "Menü-Eintrag 1")
MenuItem(2, "Menü-Eintrag 2")
MenuItem(3, "Menü-Eintrag 3")
EndIf
Repeat
event = WindowEvent()
WinMaus\x = WindowMouseX(TestFenster)
WinMaus\y = WindowMouseY(TestFenster)
Select event
Case #PB_Event_CloseWindow
Quit = #True
Case #PB_Event_Menu
Select EventMenu()
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case BaumElement
KlickElement = GetGadgetState(BaumElement)
If OverGadget(WinMaus, BaumElement) = #True And OverItem(WinMaus, BaumElement, KlickElement) = #True
If EventType() = #PB_EventType_LeftClick
Debug "Linksklick auf: "+Str(KlickElement)
ElseIf EventType() = #PB_EventType_RightClick
DisplayPopupMenu(PopMenu, WindowID(TestFenster))
Debug "Rechtsklick auf: "+Str(KlickElement)
EndIf
EndIf
EndSelect
EndSelect
If start = #True
While WindowEvent() : Wend
For i = 1 To CountGadgetItems(BaumElement)
AddElement(BaumAst())
BaumAst()\y = ypos
BaumAst()\h = GetRowHeight(BaumElement)
ypos = (GetRowHeight(BaumElement) * i)
Next i
; ForEach BaumAst()
; Debug BaumAst()\y + BaumAst()\h
; Next
start = #False
EndIf
Until Quit = #True
EndIf
End
Zuletzt geändert von ccode_new am 25.11.2018 14:27, insgesamt 1-mal geändert.
Betriebssysteme: div. Windows, Linux, Unix - Systeme
no Keyboard, press any key
no mouse, you need a cat
no Keyboard, press any key
no mouse, you need a cat
Re: Treegadget: Wie das Element bei Rechtsclick feststellen
Grundsätzlich ist das kein Problem, wenn man API-Codes verwendet. Es kommt nur darauf an, welche Betriebssysteme du gerne unterstützen möchtest. Wenn du eine Windows- und Linux-Version deiner Anwendung anbieten möchtest, dann kannst du die API-Codes auch verwenden. Vorausgesetzt du hast sowohl den Linux API- als auch Windows API-Code, dann hast du quasi auch eine plattformunabhängige Lösung. Wenn für dich MacOS auch wichtig ist, dann musst du noch warten, bis ein Mac-User für dich den API-Code für MacOS übersetzt.Onetime hat geschrieben:- der Code von ccode_new sieht stark nach Windows API aus wenn's denn übersetzt werden kann. Wollte ich aber vermeiden. Trotzdem Danke!
Dank ccode_new hast du jetzt schon einen Code, der sowohl unter Windows als auch unter Linux funktioniert. Das wäre genauso wie, wenn du eine native PB-Funktion verwendest.
Re: Treegadget: Wie das Element bei Rechtsclick feststellen
Das ganze verhält sich unter Windows sehr mysteriös.
Manchmal funktioniert es einwandfrei (am Anfang), aber nach kurzer Laufzeit des Programms funktioniert die Eventabfrage nicht mehr korrekt. (Nur bei Windows und beim Rechtsklick!) Sehr seltsames Verhalten.
Manchmal funktioniert es einwandfrei (am Anfang), aber nach kurzer Laufzeit des Programms funktioniert die Eventabfrage nicht mehr korrekt. (Nur bei Windows und beim Rechtsklick!) Sehr seltsames Verhalten.
Betriebssysteme: div. Windows, Linux, Unix - Systeme
no Keyboard, press any key
no mouse, you need a cat
no Keyboard, press any key
no mouse, you need a cat