demo-text-scrolltoend.lua 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. return function(parent, dir)
  2. local lgi = require 'lgi'
  3. local GLib = lgi.GLib
  4. local Gtk = lgi.Gtk
  5. local window = Gtk.Window {
  6. title = "Automatic scrolling",
  7. default_width = 600,
  8. default_height = 400,
  9. Gtk.Box {
  10. orientation = 'HORIZONTAL',
  11. spacing = 6,
  12. homogeneous = true,
  13. Gtk.ScrolledWindow {
  14. Gtk.TextView {
  15. id = 'view1',
  16. expand = true,
  17. }
  18. },
  19. Gtk.ScrolledWindow {
  20. Gtk.TextView {
  21. id = 'view2',
  22. expand = true,
  23. }
  24. },
  25. },
  26. }
  27. for i = 1, 2 do
  28. local view = window.child['view' .. i]
  29. local buffer = view.buffer
  30. local timer
  31. if i == 1 then
  32. -- If we want to scroll to the end, including horizontal
  33. -- scrolling, then we just create a mark with right gravity at
  34. -- the end of the buffer. It will stay at the end unless
  35. -- explicitely moved with Gtk.TextBuffer.move_mark().
  36. local mark = buffer:create_mark(nil, buffer:get_end_iter(), false)
  37. local count = 0
  38. timer = GLib.timeout_add(
  39. GLib.PRIORITY_DEFAULT, 50,
  40. function()
  41. -- Insert to the 'end' mark.
  42. buffer:insert(buffer:get_iter_at_mark(mark),
  43. '\n' .. (' '):rep(count)
  44. .. "Scroll to end scroll to end scroll to end "
  45. .."scroll to end ",
  46. -1)
  47. -- Scroll so that the mark is visible onscreen.
  48. view:scroll_mark_onscreen(mark)
  49. -- Move to the next column, or if we got too far, scroll
  50. -- back to left again.
  51. count = (count <= 150) and (count + 1) or 0
  52. return true
  53. end)
  54. else
  55. -- If we want to scroll to the bottom, but not scroll
  56. -- horizontally, then an end mark won't do the job. Just use
  57. -- Gtk.TextView.scroll_mark_onscreen() explicitely when
  58. -- needed.
  59. local count = 0
  60. local mark = buffer:create_mark(nil, buffer:get_end_iter(), true)
  61. timer = GLib.timeout_add(
  62. GLib.PRIORITY_DEFAULT, 100,
  63. function()
  64. -- Insert some text into the buffer.
  65. local iter = buffer:get_end_iter()
  66. buffer:insert(iter,
  67. '\n' .. (' '):rep(count)
  68. .. "Scroll to bottom scroll to bottom scroll to bottom "
  69. .."scroll to bottom ",
  70. -1)
  71. -- Move the iterator to the beginning of line, so we don't
  72. -- scroll in horizontal direction.
  73. iter:set_line_offset(0)
  74. -- Place mark at iter.
  75. buffer:move_mark(mark, iter)
  76. -- Scroll the mark onscreen.
  77. view:scroll_mark_onscreen(mark)
  78. -- Move to the next column, or if we got too far, scroll
  79. -- back to left again.
  80. count = (count <= 40) and (count + 1) or 0
  81. return true
  82. end)
  83. end
  84. -- Make sure that the timer is destroyed when the view is destroyed too.
  85. function view:on_destroy()
  86. GLib.source_remove(timer)
  87. end
  88. end
  89. window:show_all()
  90. return window
  91. end,
  92. "Text Widget/Automatic scrolling",
  93. table.concat {
  94. [[This example demonstrates how to use the gravity of Gtk.TextMarks ]],
  95. [[to keep a text view scrolled to the bottom when appending text.]]
  96. }