gtksourceview中的代码折叠

时间:2012-06-07 02:46:07

标签: c gtk gtksourceview

我在https://live.gnome.org/GtkSourceView上看到“我们现在可以使用gtk + 2.8支持GtkSourceView中的代码折叠”。然而,我在任何地方都找不到任何例子。它准备好了吗?是否有任何可以提供球的例子?

我已经阅读了错误报告,我已经通过电子邮件向Bijan Binaee发送了我的帮助,但没有收到任何回复。有人有任何见解吗?感谢。

2 个答案:

答案 0 :(得分:0)

对于邮件很抱歉,我可能错过了

有一些基于GTef的GTK Source View代码折叠工作。 您可以在This repository

上找到最新的工作来源

您还可以查看bugzilla page

答案 1 :(得分:0)

我最近重新讨论了这个主题,并且能够拼凑出一个简单的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主题的类型。

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