editorgadget scrollen (gelöst)

In dieser Linux-Ecke dürfen nur Themen rund um Linux geschrieben werden.
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
Shardik
Beiträge: 746
Registriert: 25.01.2005 12:19

Re: editorgadget scrollen (gelöst)

Beitrag von Shardik »

Kukulkan hat geschrieben:Allerdings muss ich vorher noch die Positionen ermitteln, damit ich bei einem Restart des Programms an exakt die selbe Position scrollen kann. Hat jemand auch dazu die passenden Befehle um die Position zu ermitteln?
Ich hatte im englischen Forum bereits einmal ein Beispiel von Blue, das unter Windows die oberste sichtbare Zeile in einem ListViewGadget ermittelt, um den Linux- und Mac-spezifischen Teil erweitert:
http://www.purebasic.fr/english/viewtop ... 25&start=6

Für ein ListIconGadget muß in der dort gezeigten Prozedur GetVisibleTopRow() lediglich für Windows in der SendMessage_()-Funktion die Konstante #LB_GETTOPINDEX (ListBox bei Microsoft, ListViewGadget bei PureBasic) gegen #LVM_GETTOPINDEX (ListView bei Microsoft, ListIconGadget bei PureBasic) ausgetauscht werden.

Ich habe trotzdem noch einmal ein komplett neues Beispiel erstellt, das bei Betätigen der Schaltfläche "Get current top row" im Fenstertitel die Zeilennummer der obersten sichtbaren Zeile anzeigt. Zu beachten ist, dass - wie in meinem englischen Posting erwähnt - betriebssystembedingt bei Linux und MacOS als oberste Zeile auch eine oberste Zeile angegeben wird, die nur teilweise sichtbar ist. Wenn man nur die Zeilennummer der obersten voll sichtbaren Zeile haben möchte, müßte man die Zeilennummer bei Linux und MacOS entsprechend aufrunden.

Ich habe das Beispiel erfolgreich unter folgenden Betriebssystemen getestet:
- MacOS X 10.6.8 (Snow Leopard)
- Ubuntu 12.04 x64 mit KDE (Gtk2 und Gtk3)
- Windows 7 x64 SP1

Code: Alles auswählen

CompilerIf #PB_Compiler_OS = #PB_OS_Linux
  ImportC ""
    gtk_tree_view_get_visible_range(*TreeView.GtkTreeView, *StartPath, *EndPath)
  EndImport
CompilerEndIf

Procedure.I GetVisibleTopRow(ListIconID.I)
  Protected VisibleTopRow.I

  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Linux
      Protected *EndPath
      Protected *StartPath

      If gtk_tree_view_get_visible_range(GadgetID(ListIconID), @*StartPath, @*EndPath)
        VisibleTopRow = PeekI(gtk_tree_path_get_indices_(*StartPath))
        gtk_tree_path_free_(*StartPath)
        gtk_tree_path_free_(*EndPath)
      EndIf
    CompilerCase #PB_OS_MacOS
      Protected ContentView.I
      Protected EnclosingScrollView.I
      Protected VisibleRange.NSRange
      Protected VisibleRect.NSRect
      
      ; ----- Get scroll view inside of ListIconGadget
      EnclosingScrollView = CocoaMessage(0, GadgetID(ListIconID), "enclosingScrollView")
      
      If EnclosingScrollView
        ContentView = CocoaMessage(0, EnclosingScrollView, "contentView")
        ; ----- Get visible area
        ;       (automatically subtract horizontal scrollbar if shown)
        CocoaMessage(@VisibleRect, ContentView, "documentVisibleRect")
        ; ----- Subtract border width
        If CocoaMessage(0, EnclosingScrollView, "borderType") > 0
          VisibleRect\size\height - 5
        EndIf
        ; ----- Get visible top row
        CocoaMessage(@VisibleRange, GadgetID(ListIconID), "rowsInRect:@", @VisibleRect)
        VisibleTopRow = Int(VisibleRange\location)
      EndIf
    CompilerCase #PB_OS_Windows
      VisibleTopRow = SendMessage_(GadgetID(ListIconID), #LVM_GETTOPINDEX, 0, 0)
  CompilerEndSelect

  ProcedureReturn VisibleTopRow
EndProcedure

OpenWindow(0, 100, 100, 200, 155, "")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 55, "Column 1",
  100)
ButtonGadget(1, 10, WindowHeight(0) - 35, WindowWidth(0) - 20, 25,
  "Get current top row")

For i = 1 To 50
  AddGadgetItem(0, -1, "Item " + Str(i))
Next i

SetWindowTitle(0, "Top row: " + Str(GetVisibleTopRow(0) + 1))

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 1
        SetWindowTitle(0, "Top row: " + Str(GetVisibleTopRow(0) + 1))
      EndIf
  EndSelect
ForEver
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

Re: editorgadget scrollen (gelöst)

Beitrag von Kukulkan »

Hallo Shardik,

Super, DANKE! :allright: <)
NeoChris
Beiträge: 205
Registriert: 21.11.2013 21:17
Wohnort: Schweiz
Kontaktdaten:

Re: editorgadget scrollen (gelöst)

Beitrag von NeoChris »

Warum heisst Listicongadget Listview und ListViewGadget Listbox? Warum so verdreht? Warum nicht einheitlich Listbox = Listboxgadget und Listview = Listviewgadget ?
Wie kam man den überhaupt auf diese Idee mit den Bezeichnungen? Hat das einen bestimmten Grund? Heisst auf Linux diese gtk Controls so? oder beim Macintosh? :?
NeoChris
Beiträge: 205
Registriert: 21.11.2013 21:17
Wohnort: Schweiz
Kontaktdaten:

Re: editorgadget scrollen (gelöst)

Beitrag von NeoChris »

Ich warte schon so lange auf eine Antwort und fast jeden Tag schau ich rein aber immer noch keine Antwort. Weiss den keiner warum das so is?
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: editorgadget scrollen (gelöst)

Beitrag von NicTheQuick »

Nein. :wink:
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: editorgadget scrollen (gelöst)

Beitrag von GPI »

NeoChris hat geschrieben:Ich warte schon so lange auf eine Antwort und fast jeden Tag schau ich rein aber immer noch keine Antwort. Weiss den keiner warum das so is?
Vermutlich historisch begründet. Ich würde auf die Amiga-Version tippen. Möglich das es dort "gedreht" ist.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
pickelrobert
Beiträge: 207
Registriert: 09.12.2004 22:09

Re: editorgadget scrollen (nur zum Teil gelöst)

Beitrag von pickelrobert »

Ich referenziere hier folgendes Beispiel: https://www.purebasic.fr/english/viewtopic.php?p=557120

Das funktioniert leider nur zum Teil. Wenn während des Hinzufügens "EnsureVisible()" aufgerufen, bleibt es irgendwo in der Mitte stehen...

Code: Alles auswählen

EnableExplicit

ImportC ""
  gtk_text_buffer_get_iter_at_line(*TextBuffer.GtkTextBuffer, *Iter, LineNumber.L)
  gtk_text_view_get_buffer(*TextView.GtkTextView)
  gtk_text_view_scroll_to_iter(*TextView.GtkTextView, *Iter, WithinMargin.D, UseAlign.I, xAlign.D, yAlign.D)
EndImport

Define i.I
Global Iter.GtkTextIter
Global *TextBuffer.GtkTextBuffer

Procedure EnsureVisible(Gadget.l)
  *TextBuffer = gtk_text_view_get_buffer(GadgetID(Gadget))
  gtk_text_buffer_get_iter_at_line(*TextBuffer, @Iter, CountGadgetItems(Gadget) - 1)
  gtk_text_view_scroll_to_iter(GadgetID(Gadget), Iter, 0.0, #False, 0.0, 0.0)
EndProcedure

OpenWindow(0, 100, 100, 180, 120, "EditorGadget", #PB_Window_SystemMenu)
EditorGadget(0, 5, 5, WindowWidth(0) - 10, WindowHeight(0) - 45)
ButtonGadget(1, WindowWidth(0) / 2 - 60, WindowHeight(0) - 33, 120, 25, "Scroll to last line")

For i = 1 To 20
  AddGadgetItem(0, - 1, "Line number " + Trim(Str(i)))
  EnsureVisible(0)
Next

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 1 And EventType() = #PB_EventType_LeftClick
         EnsureVisible(0)
      EndIf
  EndSelect
ForEver
Habe ich irgendetwas übersehen?
Benutzeravatar
mk-soft
Beiträge: 3845
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: editorgadget scrollen (gelöst)

Beitrag von mk-soft »

Ist eine kleine Macke unter Linux womit man leben kann.
Man muss einmal alle Events verarbeiten (löschen) damit die GUI fertig aufgebaut ist ;)

P.S. Habe den Code mal etwas aufgeräumt.

P.S. 2
Geht noch kürzer ...

Update 2

Code: Alles auswählen

EnableExplicit

Define i

Macro DoEvents()
  While WindowEvent() : Wend
EndMacro

Procedure EnsureVisibleLine(Gadget, Line = 0)
  Protected *Gadget.GtkWidget, *TextBuffer.GtkTextBuffer, Iter.GtkTextIter
  
  *Gadget = GadgetID(Gadget)
  *TextBuffer = gtk_text_view_get_buffer_(*Gadget)
  If Line
    gtk_text_buffer_get_iter_at_line_(*TextBuffer, @Iter, Line - 1)
  Else
    gtk_text_buffer_get_end_iter_(*TextBuffer, @Iter)
  EndIf
  gtk_text_view_scroll_to_iter_(*Gadget, Iter, 0.0, #False, 0.0, 0.0)
EndProcedure

OpenWindow(0, 100, 100, 180, 160, "EditorGadget", #PB_Window_SystemMenu)
EditorGadget(0, 5, 5, WindowWidth(0) - 10, WindowHeight(0) - 45)
ButtonGadget(1, WindowWidth(0) / 2 - 60, WindowHeight(0) - 33, 120, 25, "Scroll to last line")

For i = 1 To 20
  AddGadgetItem(0, - 1, "Line number " + Trim(Str(i)))
Next
DoEvents()
EnsureVisibleLine(0, 10)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 1 And EventType() = #PB_EventType_LeftClick
        EnsureVisibleLine(0)
      EndIf
  EndSelect
ForEver
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
pickelrobert
Beiträge: 207
Registriert: 09.12.2004 22:09

Re: editorgadget scrollen (gelöst)

Beitrag von pickelrobert »

Ein interessanter Ansatz. Danke.
Antworten