Seite 1 von 2

StringGadgetInhalt Selektieren bei Fokuserhalt

Verfasst: 16.07.2017 22:46
von Bisonte
Hallo.

Hier mal eine Frage an die Linuxgemeinde :

Ich habe ein StringGadget, dessen Inhalt selektiert werden soll, wenn es den Fokus erhält.

Wenn ich gtk_editable_select_region_() in der Haupt Event Schleife aufrufe, funktioniert es.
Wenn ich das ganze aber in eine Prozedur verfrachte und mit BindGadgetEvent() automatisch
aufrufen lassen möchte, klappt es nicht mehr. Weiss jemand wie ich das mit BindGadgetEvent()
hinbekomme ?

Unter Windows hatte ich ähnliches Problem, dort half es aus dem SendMessage_() ein PostMessage_()
Aufruf zu machen, evt. ist es hier das gleiche, nur kenne ich die ganze API Geschichte nicht wirklich ...

Code: Alles auswählen

; Funktioniert !
OpenWindow(0, 0, 0, 200, 100, "Autoselect text", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(1, 10, 10, 20, 20, "A")
StringGadget(2, 50, 40, 100, 20, "Test")
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 2
        If EventType() = #PB_EventType_Focus
          gtk_editable_select_region_(GadgetID(2), 0, Len(GetGadgetText(2)))
        EndIf
      EndIf
  EndSelect
ForEver 

Code: Alles auswählen

; Soll funktionieren ! (leider macht es nichts)
Procedure.i MyStringEvent()
  
  Gadget = EventGadget()
  
  Select EventType()
    Case #PB_EventType_Focus
      gtk_editable_select_region_(GadgetID(Gadget), 0, Len(GetGadgetText(Gadget)))   
  EndSelect
    
EndProcedure

OpenWindow(0, 0, 0, 200, 100, "Autoselect text", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(1, 10, 10, 20, 20, "A")
StringGadget(2, 50, 40, 100, 20, "Test")
BindGadgetEvent(2, @MyStringEvent(), #PB_EventType_Focus)
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver 
Der Button ist zum Fokus verlieren da ;)

Re: StringGadgetInhalt Selektieren bei Fokuserhalt

Verfasst: 17.07.2017 03:46
von Nino
Die beiden folgenden Codes funktionieren hier mit PB 5.44 LTS unter Linux Mint 18.1 Cinnamon 32 Bit.

Code: Alles auswählen

OpenWindow(0, 0, 0, 200, 100, "Autoselect text", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(1, 10, 10, 20, 20, "A")
StringGadget(2, 50, 40, 100, 20, "Test")

Repeat
   Select WaitWindowEvent()
      Case #PB_Event_Gadget
         If EventGadget() = 2
            Select EventType()
               Case #PB_EventType_Focus
                  gtk_editable_select_region_(GadgetID(2), 0, Len(GetGadgetText(2)))
               Case #PB_EventType_LostFocus
                  gtk_editable_select_region_(GadgetID(2), 0, 0)
            EndSelect
         EndIf
         
      Case #PB_Event_CloseWindow
         Break
   EndSelect
ForEver

Code: Alles auswählen

Procedure.i MyStringEvent()
   Select EventType()
      Case #PB_EventType_Focus
         gtk_editable_select_region_(GadgetID(2), 0, Len(GetGadgetText(2)))
      Case #PB_EventType_LostFocus
         gtk_editable_select_region_(GadgetID(2), 0, 0)
   EndSelect
EndProcedure


OpenWindow(0, 0, 0, 200, 100, "Autoselect text", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(1, 10, 10, 20, 20, "A")
StringGadget(2, 50, 40, 100, 20, "Test")
BindGadgetEvent(2, @MyStringEvent())

Repeat
   Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
         Break
   EndSelect
ForEver

Re: StringGadgetInhalt Selektieren bei Fokuserhalt

Verfasst: 17.07.2017 09:23
von Bisonte
Faszinierend. Ich habe allerdings Linux Mint 18.1 Cinammon 64Bit laufen und PB5.60

Der Code mit der Eventschleife funktioniert (wie im Eingangspost erwähnt.)
Der untere mit BindEventGadget nicht. Irgendwie seltsam...

Ich werde es glatt nachher mit der 5.44 probieren...

Re: StringGadgetInhalt Selektieren bei Fokuserhalt

Verfasst: 17.07.2017 10:51
von Kiffi
@Nino: die BindGadgetEvent()-Variante funktioniert bei mir auch nicht wirklich.

Wenn man in die Mitte von 'Test' klickt, so wird der gesamte Text kurzzeitig selektiert. Danach steht der Cursor dort, wo man hingeklickt hat und die Selektion ist weg.

Grüße ... Peter (Linux Mint 18.2 Cinnamon 64-bit / PB 5.60 x64)

Re: StringGadgetInhalt Selektieren bei Fokuserhalt

Verfasst: 17.07.2017 10:56
von Nino
@Bisonte:
Meine Vermutung war/ist, dass das Problem evtl. durch diese Zeile bei Dir

Code: Alles auswählen

BindGadgetEvent(2, @MyStringEvent(), #PB_EventType_Focus)
verursacht wird.

Deshalb habe ich BindGadgetEvent() ohne #PB_EventType_Focus aufgerufen.

@Kiffi:
Uuups, Mausklick hatte ich gar nicht getestet. :oops:
Ich hatte es nur mit Drücken der Tab-Taste probiert.

Im Moment (Büro-PC ohne Linux) kann ich's nicht neu testen.

Re: StringGadgetInhalt Selektieren bei Fokuserhalt

Verfasst: 17.07.2017 10:57
von NicTheQuick
Bei mir wird es beim LeftButtonUp wieder deselektiert. Das heißt, wenn ich rein klicke und die Taste halte, dann ist der Text markiert. Wenn ich dann die Maus etwas verschiebe, bleibt es auch markiert. Lasse ich die Taste wieder los, ohne sie vorher verschoben zu haben, dann wird erst wieder deselektiert. Man müsste also vielleicht irgendwie LeftButtonUp abfangen können.

Mit Tab funktioniert es wunderbar.

Re: StringGadgetInhalt Selektieren bei Fokuserhalt

Verfasst: 17.07.2017 12:47
von Bisonte
@Nic: Stimmt. So ist mir das gar nicht aufgefallen. Unter Windows reicht ein Klick ins Gadget, und dadurch erhält
es den Fokus, somit wird es selektiert. Warum muss man denn hier nun die Maustaste gedrückt halten ?

Ich hab den code ja wie oben (also ohne das "deselektieren") und das Verhalten ist genau das gleiche.
Allerdings auch nur, wenn der Cursor irgendwo in dem Text steht. Wenn er am Ende steht passiert nichts.

Nun hab ich das Problem, das das StringGadget nur drei EventTypes unterstützt... "Was tun?" sprach Zeus....

Re: StringGadgetInhalt Selektieren bei Fokuserhalt

Verfasst: 17.07.2017 17:48
von Omi
Hi!
Unterm Linux-Gtk ist es so, dass für Mausklicks auf ein Widget (Gadget) immer eine Sequenz von Events abgearbeitet wird.
Wird z.B. ein Linksklick (besteht aus Press und Release) erkannt, wird gewartet ob nicht ein Doppelklick folgt,
wird dann ein Doppel-Linksklick erkannt wird nochmals gewartet, ob nicht ein 3-fach-Klick folgt.
Erst nach dieser Verzögerung steht der Typ endgültig fest.

Während dieser Zeit ist ein selbstmodifizierender Code auf das Widget, das die Mausklicks erhält leider kaum oder überhaupt nicht möglich - es wird stets auf den vorherigen Zustand zurückgesetzt. (zu was die heutigen OS nebenbei so alles Zeit haben :wink: )
Erst danach ist eine Änderung des betroffenen Gadgets möglich.

Ich hab mir kürzlich mit einem zusammengebastelten DelayedPostEvent() geholfen, um zum Beispiel ein SplitterGadget durch Doppelklick auf den Griff auf bestimmte Werte zu setzen. Innerhalb des/der Callbacks sprang er stets auf den vorherigen Werte zurück.
Ne andere Lösung wüßte ich im Moment auch nicht.

Gruß Charly

Re: StringGadgetInhalt Selektieren bei Fokuserhalt

Verfasst: 17.07.2017 18:41
von Nino
Es scheint hier zu funktionieren, wenn Maus-Linksklicks in einer eigenen Ereignisprozedur entsprechend behandelt werden:

Code: Alles auswählen

; PB 5.44 LTS unter Linux Mint 18.1 (32 Bit)

EnableExplicit

; Konstanten für den Fokus in Bezug auf das Stringgadget
Enumeration
   #Focus_Lost
   #Focus_Got
EndEnumeration

Global.i gFocusState = #Focus_Lost

Procedure MyStringEvent()
   Select EventType()
      Case #PB_EventType_Focus
         gtk_editable_select_region_(GadgetID(2), 0, Len(GetGadgetText(2)))
         gFocusState = #Focus_Got
      Case #PB_EventType_LostFocus
         gtk_editable_select_region_(GadgetID(2), 0, 0)
         gFocusState = #Focus_Lost
   EndSelect
EndProcedure

Procedure MyLeftClickEvent()
   Static.i isSelected = #False
   
   If gFocusState = #Focus_Got
      If isSelected = #False
         gtk_editable_select_region_(GadgetID(2), 0, Len(GetGadgetText(2)))
         isSelected = #True
      Else
         gtk_editable_select_region_(GadgetID(2), 0, 0)
         isSelected = #False
      EndIf
   EndIf   
EndProcedure


OpenWindow(0, 0, 0, 200, 100, "Autoselect text", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(1, 10, 10, 20, 20, "A")
StringGadget(2, 50, 40, 100, 20, "Test")
BindGadgetEvent(2, @MyStringEvent())
BindEvent(#PB_Event_LeftClick, @MyLeftClickEvent())

Repeat
   Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
         Break
   EndSelect
ForEver

Re: StringGadgetInhalt Selektieren bei Fokuserhalt

Verfasst: 17.07.2017 20:09
von Bisonte
Ok Da alles nicht so wirklich den erwünschten Effekt hat, muss es dann wohl doch die Haupt
Schleife sein. Und nochmal nebenbei : Wenn das "deselektieren" automatisch bei LostFocus
gemacht wird, kann man mit dem selektierten Inhalt nichts anfangen (Rechtsklick und kopieren
ist Fokusverlust, weil ein Popupmenu aufgeht!)

Also doch nach Abfrage ob das Event was reinkommt von einem Gadget kommt, allgemein nach String schauen
und bei Fokuserhalt den Text markieren. So klappt das.

Code: Alles auswählen

Procedure.i AutoSelectString()
  
  If GadgetType(EventGadget()) = #PB_GadgetType_String
    If EventType() = #PB_EventType_Focus
      gtk_editable_select_region_(GadgetID(EventGadget()), 0, Len(GetGadgetText(EventGadget())))   
    EndIf
  EndIf
  
EndProcedure

OpenWindow(0, 0, 0, 200, 100, "Autoselect text", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(1, 10, 10, 20, 20, "A")
StringGadget(2, 50, 40, 100, 20, "Test")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      AutoSelectString()
  EndSelect
ForEver
Schade eigentlich, weil das BindGadgetEvent ja eigentlich für genau sowas da ist ...