Skip to content

Commit

Permalink
Merge pull request #92 from billyeatcookies/dev
Browse files Browse the repository at this point in the history
Code folding
  • Loading branch information
tomlin7 authored Jul 26, 2023
2 parents 4ec0474 + ca1ab38 commit 8287d63
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 18 deletions.
5 changes: 4 additions & 1 deletion biscuit/core/components/editors/editor.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from biscuit.core.components.utils import Frame
from biscuit.core.components.utils import Frame, IconButton


class BaseEditor(Frame):
Expand All @@ -20,5 +20,8 @@ def __init__(self, master, path=None, exists=None, editable=True, *args, **kwarg

self.__buttons__ = ()

def create_buttons(self, editorbar):
self.__buttons__ = [IconButton(editorbar, *button) for button in self.__buttons__]

def save(self, *_):
...
122 changes: 122 additions & 0 deletions biscuit/core/components/editors/texteditor/codefolding_demo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import tkinter as tk
from tkinter import INSERT, NE, Canvas, Menubutton
from tkinter.font import Font


class LineNumbers(Canvas):
def __init__(self, master, text=None, *args, **kwargs):
super().__init__(master, *args, **kwargs)
self.config(width=50, bd=0, highlightthickness=0)
self.text = text
self.text.config(bd=0, highlightthickness=0)
self.text.tag_config("sel", background="#48484f", foreground="#e1e1e6")
self.text.bind("<Configure>", self.redraw)
self.text.bind("<<Change>>", self.redraw)

def attach(self, text):
self.text = text

def set_bar_width(self, width):
self.configure(width=width)

def get_indentation_level(self, line):
"""Get the indentation level of a given line."""
return len(line) - len(line.lstrip())

def redraw(self, *_):
self.delete(tk.ALL)

prev_indent = 0
i = self.text.index("@0,0")
while True:
dline = self.text.dlineinfo(i)
if dline is None:
break

y = dline[1]
linenum = str(i).split(".")[0]

# Get the text content of the current line
line_content = self.text.get(f"{linenum}.0", f"{linenum}.end")
current_indent = self.get_indentation_level(line_content)

# Determine if the current line has more indentation than the previous line
if current_indent > prev_indent:
line_num_with_indent = f"+ {linenum}"
elif current_indent < prev_indent:
line_num_with_indent = f"- {linenum}"
else:
line_num_with_indent = linenum

# to highlight the current line
curline = self.text.dlineinfo(tk.INSERT)
cur_y = curline[1] if curline else None

if not cur_y:
i = self.text.index(f"{i}+1line")
continue

if y == cur_y:
self.create_text(40, y, anchor=tk.NE, text=line_num_with_indent, font=("Consolas", 14), fill="#83838f", tag=i)
else:
self.create_text(40, y, anchor=tk.NE, text=line_num_with_indent, font=("Consolas", 14), fill="#525259", tag=i)


# Update the previous indentation level
prev_indent = current_indent
i = self.text.index(f"{i}+1line")

class Text(tk.Text):
def __init__(self, master=None, **kw):
super().__init__(master, **kw)
self.mark_set('input', 'insert')
self.mark_gravity('input', 'left')

self._orig = self._w + "_orig"
self.tk.call("rename", self._w, self._orig)
self.tk.createcommand(self._w, self._proxy)

def _proxy(self, *args):
if args[0] == 'get' and (args[1] == tk.SEL_FIRST and args[2] == tk.SEL_LAST) and not self.tag_ranges(tk.SEL):
return
if args[0] == 'delete' and (args[1] == tk.SEL_FIRST and args[2] == tk.SEL_LAST) and not self.tag_ranges(tk.SEL):
return

cmd = (self._orig,) + args
result = self.tk.call(cmd)

if (args[0] in ("insert", "replace", "delete") or args[0:3] == ("mark", "set", "insert")
or args[0:2] == ("xview", "moveto") or args[0:2] == ("yview", "moveto")
or args[0:2] == ("xview", "scroll") or args[0:2] == ("yview", "scroll")):
self.event_generate("<<Change>>", when="tail")

return result


class ExampleApp:
def __init__(self, root):
self.font = ("Consolas", 14)

self.text_widget = Text(root, wrap=tk.NONE, font=self.font, bg="#2e2e32", fg="#e1e1e6")
self.line_numbers = LineNumbers(root, text=self.text_widget, bg="#2e2e32")

self.line_numbers.pack(side=tk.LEFT, fill=tk.Y)
self.text_widget.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

# Sample text with indentation for testing code folding
sample_code = """\
def foo():
print("Hello,")
print("World!")
if True:
print("This is a nested block.")
print("Indented lines are foldable.")
print("Code folding based on indentation.")
"""
self.text_widget.insert(tk.END, sample_code)
self.line_numbers.redraw()

if __name__ == "__main__":
root = tk.Tk()
app = ExampleApp(root)
root.mainloop()
9 changes: 4 additions & 5 deletions biscuit/core/components/games/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def register_game(game):

class Game(Frame):
"""
responsible for picking the right game
Responsible for picking the right game
name - name of game to opened
"""
Expand All @@ -46,12 +46,11 @@ def __init__(self, master, name, *args, **kwargs):
self.exists = False
self.diff = False
self.showpath = False
self.content = None

self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(0, weight=1)
self.game = get_game(name=name)(self)
self.game.grid(row=0, column=0, sticky=tk.NSEW)
self.content = get_game(name=name)(self)
self.content.grid(row=0, column=0, sticky=tk.NSEW)

def focus(self):
self.game.focus_get()
self.content.focus_get()
8 changes: 5 additions & 3 deletions biscuit/core/components/games/game.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import tkinter as tk

from biscuit.core.components.utils import Frame
from biscuit.core.components.utils import Frame, IconButton


class BaseGame(Frame):
Expand All @@ -15,11 +15,13 @@ def __init__(self, master, path=None, *args, **kwargs):

self.exists = False
self.showpath = False
self.content = None
self.diff = False
self.editable = False

self.__buttons__ = ()
self.__buttons__ = (('refresh', self.reload), )

def create_buttons(self, editorbar):
self.__buttons__ = [IconButton(editorbar, *button) for button in self.__buttons__]

def reload(self, *_):
...
Expand Down
9 changes: 5 additions & 4 deletions biscuit/core/layout/base/content/editors/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import tkinter as tk


from .editorsbar import Editorsbar
from .empty import Empty

from biscuit.core.components.editors import Editor
from biscuit.core.components.games import Game
from biscuit.core.components.utils import Frame

from .editorsbar import Editorsbar
from .empty import Empty


class EditorsPane(Frame):
"""
Expand Down Expand Up @@ -54,6 +53,8 @@ def add_editors(self, editors):
def add_editor(self, editor):
"Appends a editor to list. Create a tab."
self.editors.append(editor)
if editor.content:
editor.content.create_buttons(self.editorsbar.container)
self.tabs.add_tab(editor)

def delete_all_editors(self):
Expand Down
10 changes: 5 additions & 5 deletions biscuit/core/layout/base/content/editors/editorsbar.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import tkinter as tk
from tkinter.constants import *

from biscuit.core.components.utils import Frame, IconButton

from .tabs import Tabs
from biscuit.core.components.utils import IconButton, Frame


class Editorsbar(Frame):
Expand All @@ -16,12 +17,11 @@ def __init__(self, master, *args, **kwargs):
self.buttons = []
self.default_buttons = (('ellipsis',),)

# TODO like panelbar, add __buttons__ to BaseEditor
self.buttonframe = Frame(self)
self.buttonframe.pack(fill=BOTH, side=RIGHT, pady=5, padx=10)
self.container = Frame(self, **self.base.theme.layout.base.content.editors.bar)
self.container.pack(fill=BOTH, side=RIGHT, padx=(0, 10))

for button in self.default_buttons:
IconButton(self.buttonframe, *button).pack(side=RIGHT)
IconButton(self.container, *button).pack(side=RIGHT)

def add_buttons(self, buttons):
for button in buttons:
Expand Down

0 comments on commit 8287d63

Please sign in to comment.