4

我在https://live.gnome.org/GtkSourceView上看到“我们现在可以使用 gtk+ 2.8 支持 GtkSourceView 中的代码折叠”。然而我在任何地方都找不到任何例子。准备好使用了吗?有没有可以提供的例子来让事情顺利进行?

我已阅读错误报告,并已通过电子邮件向 Bijan Binaee 提供帮助,但没有收到任何回复。任何人有任何见解?谢谢。

4

2 回答 2

1

我最近重新审视了这个话题,并且能够拼凑出一个简单的 python 示例,它演示了在 gtk 中完成代码折叠的一种方法:

#!/usr/bin/python

import gi
gi.require_version('Gtk', '3.0')
gi.require_version('GtkSource', '3.0')

import signal
import sys,os
import cairo
from gi.repository import Gtk as gtk
from gi.repository import Gdk as gdk
from gi.repository import GObject as gobject
from gi.repository import GtkSource as gtksource
from gi.repository.GdkPixbuf import Pixbuf

theme = 'light'     # [light/dark] type of gtk theme in use

class Editor:

        def check_sigint_timer(self,timeout):
                gobject.timeout_add_seconds(timeout, self.check_sigint)

        def check_sigint(self):
                return True

        def quit_activated(self):
                dialog = gtk.MessageDialog(parent=self.window, type=gtk.MessageType.QUESTION, buttons=gtk.ButtonsType.YES_NO)   
                dialog.set_title("Question")
                dialog.set_position(gtk.WindowPosition.CENTER_ALWAYS)
                dialog.set_markup("Are you sure you want to quit?")
                response = dialog.run()
                if response == gtk.ResponseType.YES:
                    dialog.destroy()
                    gtk.main_quit()
                elif response == gtk.ResponseType.NO:
                    dialog.destroy()

        def delete_event_cb(self, widget, data=None):
                print "delete_event signal occurred"
                self.quit_activated()
                return True

        def destroy_cb(self, widget, data=None):
                print "destroy signal occurred"
                self.quit_activated()

        def signal_handler(self, signal, frame):
                print '\nYou pressed Ctrl+C!, exiting'
                gtk.main_quit()

        def get_fold_minus_pixbuf(self):
                w = 24
                h = 24
                surface = cairo.ImageSurface (cairo.FORMAT_ARGB32, w, h)
                cr = cairo.Context (surface)
                if theme == 'dark':
                    cr.set_source_rgb(0.94, 0.94, 0.94)
                else:       
                    cr.set_source_rgb(0., 0., 0.)
                cr.rectangle(0,0,w,h)
                cr.fill()

                if theme == 'dark':
                    cr.set_source_rgb(0., 0., 0.)
                else:       
                    cr.set_source_rgb(0.94, 0.94, 0.94)
                cr.move_to (w/5.,h/2.)
                cr.line_to (w*0.8,h/2.)
                cr.stroke ()

                pixbuf = gdk.pixbuf_get_from_surface(surface,0,0,w,h)
                return pixbuf

        def get_fold_plus_pixbuf(self):
                w = 24
                h = 24
                surface = cairo.ImageSurface (cairo.FORMAT_ARGB32, w, h)
                cr = cairo.Context (surface)
                if theme == 'dark':
                    cr.set_source_rgb(0.94, 0.94, 0.94)
                else:       
                    cr.set_source_rgb(0., 0., 0.)
                cr.rectangle(0,0,w,h)
                cr.fill()

                if theme == 'dark':
                    cr.set_source_rgb(0., 0., 0.)
                else:       
                    cr.set_source_rgb(0.94, 0.94, 0.94)
                cr.move_to (w/5.,h/2.)
                cr.line_to (w*0.8,h/2.)
                cr.stroke ()

                cr.move_to (w/2.,h/5.)
                cr.line_to (w/2.,h*0.8)
                cr.stroke ()

                pixbuf = gdk.pixbuf_get_from_surface(surface,0,0,w,h)
                return pixbuf

        def get_fold_vert_pixbuf(self):
                w = 24
                h = 24
                surface = cairo.ImageSurface (cairo.FORMAT_ARGB32, w, h)
                cr = cairo.Context (surface)
                if theme == 'dark':
                    cr.set_source_rgb(1., 1., 1.)
                else:       
                    cr.set_source_rgb(0., 0., 0.)
                cr.move_to (w/2,0)
                cr.line_to (w/2,h)
                cr.stroke ()
                pixbuf = gdk.pixbuf_get_from_surface(surface,0,0,w,h)
                return pixbuf

        def get_fold_end_pixbuf(self):
                w = 24
                h = 24
                surface = cairo.ImageSurface (cairo.FORMAT_ARGB32, w, h)
                cr = cairo.Context (surface)
                if theme == 'dark':
                    cr.set_source_rgb(1., 1., 1.)
                else:       
                    cr.set_source_rgb(0., 0., 0.)
                cr.move_to (w/2,0)
                cr.line_to (w/2,h/2)
                cr.line_to (w,h/2)
                cr.stroke ()
                pixbuf = gdk.pixbuf_get_from_surface(surface,0,0,w,h)
                return pixbuf

        def place_mark(self,mtype,line):
                iter = self.buffer.get_iter_at_line (line)

                if mtype == '+':
                    self.buffer.create_source_mark(None, "fold_plus", iter)
                elif mtype == '-':
                    self.buffer.create_source_mark(None, "fold_minus", iter)
                elif mtype == '|':
                    self.buffer.create_source_mark(None, "fold_vert", iter)
                elif mtype == 'end':
                    self.buffer.create_source_mark(None, "fold_end", iter)

        def create_marks(self):
                pixbuf = self.get_fold_plus_pixbuf()
                mark_attr = gtksource.MarkAttributes.new()
                mark_attr.set_pixbuf(pixbuf)
                self.view.set_mark_attributes("fold_plus",mark_attr,0)

                pixbuf = self.get_fold_minus_pixbuf()
                mark_attr = gtksource.MarkAttributes.new()
                mark_attr.set_pixbuf(pixbuf)
                self.view.set_mark_attributes("fold_minus",mark_attr,0)

                pixbuf = self.get_fold_vert_pixbuf()
                mark_attr = gtksource.MarkAttributes.new()
                mark_attr.set_pixbuf(pixbuf)
                self.view.set_mark_attributes("fold_vert",mark_attr,0)

                pixbuf = self.get_fold_end_pixbuf()
                mark_attr = gtksource.MarkAttributes.new()
                mark_attr.set_pixbuf(pixbuf)
                self.view.set_mark_attributes("fold_end",mark_attr,0)

        def mark_activated_cb(self,view,iter,event):
                line = iter.get_line()
                marks = self.buffer.get_source_marks_at_iter(iter)          
                for mark in marks:
                    cat = mark.get_category()   
                    if cat == 'fold_minus':
                        start = self.buffer.get_iter_at_line (self.block[0]+1)
                        end = self.buffer.get_iter_at_line (self.block[1]+1)
                        self.buffer.apply_tag_by_name("invisible",start,end)

                        # remove the existing mark, then create the opposite mark
                        start = self.buffer.get_iter_at_line (self.block[0])
                        self.buffer.remove_source_marks(start,start)
                        self.place_mark('+',self.block[0])

                    elif cat == 'fold_plus':
                        start = self.buffer.get_iter_at_line (self.block[0]+1)
                        end = self.buffer.get_iter_at_line (self.block[1]+1)
                        self.buffer.remove_all_tags(start,end)

                        # remove the existing mark, then create the opposite mark
                        start = self.buffer.get_iter_at_line (self.block[0])
                        self.buffer.remove_source_marks(start,start)
                        self.place_mark('-',self.block[0])

        def __init__(self):

                signal.signal(signal.SIGINT, self.signal_handler)

                self.window = gtk.Window(gtk.WindowType.TOPLEVEL)
                self.window.connect("delete_event", self.delete_event_cb)
                self.window.connect("destroy", self.destroy_cb)
                self.window.set_border_width(10)
                self.window.maximize()

                self.view = gtksource.View()
                self.view.connect("line-mark-activated",self.mark_activated_cb)
                self.buffer = self.view.get_buffer()
                self.view.set_show_line_numbers(True)
                self.view.set_show_line_marks(True)
                sw = gtk.ScrolledWindow()
                sw.add(self.view)
                self.window.add(sw)

                path = sys.argv[0]
                txt = open(path).read()
                self.buffer.set_text(txt)

                lm = gtksource.LanguageManager.new()
                lang = lm.guess_language(path)
                self.buffer.set_highlight_syntax(True)
                self.buffer.set_language(lang)

                self.buffer.create_tag("invisible",invisible=True)

                self.block = [25,35]
                self.create_marks()
                self.place_mark('-',self.block[0])

                for i in xrange(self.block[0],self.block[1]):
                    self.place_mark('|',i)

                self.place_mark('end',self.block[1])

                self.window.show_all()

                self.check_sigint_timer(1)

        def main(self):
                gtk.main()

if __name__ == "__main__":
        ed = Editor()
        ed.main()

请务必更改主题变量以反映您碰巧使用的 gtk3 主题的类型。

如果有人能展示如何消除在排水沟中绘制的垂直线中的线间隙,将不胜感激。

于 2018-02-15T20:56:48.893 回答
0

对不起,邮件,它可能是我错过了

有一些基于 GTef 的 GTK Source View 代码折叠工作。您可以在此存储库中找到最新的工作源

您还可以查看bugzilla 页面

于 2016-09-02T08:31:24.517 回答