TkTerminal icon indicating copy to clipboard operation
TkTerminal copied to clipboard

Add a tag to stop user from editing anything.

Open littlewhitecloud opened this issue 2 years ago • 27 comments

I was testing the widget and I found we can edit the output and the path. Then the widget became what a mess. I through a simple solution to fix it:

  • Create a uneditable tag.
  • Add it to the path output and command output.

littlewhitecloud avatar Jun 04 '23 00:06 littlewhitecloud

I had fixed that with the left right up commands...

Moosems avatar Jun 04 '23 12:06 Moosems

littlewhitecloud avatar Jun 04 '23 13:06 littlewhitecloud

But I can still delete things.

littlewhitecloud avatar Jun 04 '23 13:06 littlewhitecloud

image image

littlewhitecloud avatar Jun 07 '23 11:06 littlewhitecloud

There's nothing gone.....

Moosems avatar Jun 07 '23 12:06 Moosems

6, image

littlewhitecloud avatar Jun 07 '23 13:06 littlewhitecloud

Actally, the left right up commands has problem, If I choose the text and press delete, it will still delete.

littlewhitecloud avatar Jun 09 '23 12:06 littlewhitecloud

So clicking needs a bind.

Moosems avatar Jun 09 '23 12:06 Moosems

Is there a way to give a readonly tag?

littlewhitecloud avatar Jun 10 '23 03:06 littlewhitecloud

So clicking needs a bind.

I prefer use a tag to set the text above it read only.

littlewhitecloud avatar Jun 10 '23 05:06 littlewhitecloud

There's no built in way but I can create one.

Moosems avatar Jun 10 '23 10:06 Moosems

There's no built in way but I can create one.

WOW! How?

littlewhitecloud avatar Jun 10 '23 11:06 littlewhitecloud

Bind all keypresses and button clicks and determine if the end result would be on top of any of the tag ranges. If it is, cancel the action otherwise allow it. Up and down get special treatment.

Moosems avatar Jun 10 '23 17:06 Moosems

Bind all keypresses and button clicks and determine if the end result would be on top of any of the tag ranges. If it is, cancel the action otherwise allow it. Up and down get special treatment.

Good idea, but bind a lot maybe make the program slow.

littlewhitecloud avatar Jun 11 '23 00:06 littlewhitecloud

It'll be fast enough :).

Moosems avatar Jun 11 '23 00:06 Moosems

@littlewhitecloud I'm going to do a ton of work tomorrow on the repo (eastern time US) so buckle up :D.

Moosems avatar Jun 11 '23 01:06 Moosems

@littlewhitecloud I'm going to do a ton of work tomorrow on the repo (eastern time US) so buckle up :D.

So I think We should split it out from the improve pr, create a new one and starting our trip :)

littlewhitecloud avatar Jun 11 '23 02:06 littlewhitecloud

from tkinter import Tk, Text, Event

root = Tk()
txt = Text(root)
txt.pack()

txt.tag_configure("important")

txt.insert("1.0", "Hello, World!")
txt.tag_add("important", "1.0", "1.5")
# written on phone so there may be syntax errors

def check_important(event: Event) -> None:
    # Things to check:
    # Is the text that would be gone to by typing on the same line and to the right of anything important?
    # Are we selecting stuff? In most terminals, that shouldn't even be allowed.
    # If it's a click event, is the clicked char important?
    # If any of these fail, we should return "break"
    widget = event.widget
    if widget.tag_ranges("sel"):
        widget.tag_remove("sel", "1.0", "end")
    # Determine the action (click or keypress)
    # Keypress check for a few things: is it backspace (check if previous character is a special one, up or down which inserts that line, return creates a new line and runs the code, and all modified ones like control/command-a and blocks those)
    # Clicks check for the index of the click and if it is inside one of the special we just bring it to the start of the non special chars

    important_ranges: list[tuple[str]] = widget.tag_ranges("important")
    if event.type == 4:
        # The type is a click
        click_index: str = widget.index(f"@{event.x},{event.y}).split(".")[1]
        end_line = widget.index("end-1c").split(".")[0]
        check_index = f"{end_line}.{click_index}"
        if "important" in widget.tag_names(check_index):
            # Wants to click on an important char
            # Put the cursor in the first non-important space (Len of working dir)
            ...
        return
    # The type is a keypress
    # Use keysym ("Left", "Up", "Return", "BackSpace", something for contmand-a (keysym and key combo), command-arrow, control-arrow, list is here: https://www.tcl.tk/man/tcl8.6/TkCmd/keysyms.html)
    return_keysym = 65293
    left_keysym = 65361
    right_keysym = 65363
    backspace_keysym = 
    ...

txt.bind("<Key>", check_important, add=True)
txt.bind("<Button-1>", check_important, add=True)

root.mainloop()

Moosems avatar Jun 12 '23 12:06 Moosems

@littlewhitecloud, I am still working on this from my phone but here's an update.

Moosems avatar Jun 13 '23 12:06 Moosems

# Edit it on iPad, maybe have a lot of typo
self.cursor = 0
self.text.bind(“Left”, self._left)
self.text.bind(“Right”, self._right)
self.text.bind(“Click”, self._click)
# maybe merge them into one function
def _left(self, event):
    self.cursor -= 1
    if self.cursor < 0:
       self.text[“state”] = “readonly”

def _right(self, event):
    self.index += 1
    if self.index > 0:
        self.text[“state”] = “normal”

def _click(self, event):
    self.index = #cursor index
    if self.index < 0 and self.text[“state”] == “normal”:
         self.text[“state”] = “readonly”
    elif self.index > 0 and self.text[“state”] == “readonly”:
         self.text[“state”] = “normal”

littlewhitecloud avatar Jun 14 '23 13:06 littlewhitecloud

My form, but still have a lot of logic problem, fix it later.

littlewhitecloud avatar Jun 14 '23 13:06 littlewhitecloud

Clear also needs to be a special command for typing.

Moosems avatar Jun 14 '23 16:06 Moosems

find a new and better way to improve it.

    def updates(self, _: Event) -> None:
        """Update cursor"""
        self.cursor = self.text.index("insert")
        if float(self.cursor) < float(self.latest):
            self.text.bind("<KeyPress>", self.eat, True)
            self.text.bind("<KeyPress-BackSpace>", self.eat, True)
        elif float(self.cursor) >= float(self.latest):
            self.text.unbind("<Key>")
            self.text.unbind("<KeyPress-Backspace>")

    def eat(self, _: Event) -> str:
        """Just eat"""
        return "break"

littlewhitecloud avatar Jun 26 '23 13:06 littlewhitecloud

Mine should be able to be put in a duct allowing for better handling. I'll need to finish the handler but I have a feeling it will work well.

Moosems avatar Jun 26 '23 14:06 Moosems

Mine should be able to be put in a duct allowing for better handling. I'll need to finish the handler but I have a feeling it will work well.

How long will it take to finish it?

littlewhitecloud avatar Jun 27 '23 01:06 littlewhitecloud

If it still take a long time, maybe we should fix it in another pr. Just use mine version as a temp solution. When you are finished, we can remove mine can replace with your solution.

littlewhitecloud avatar Jun 27 '23 01:06 littlewhitecloud

Yeah. I'd merge the PR and when I have a free week I'll make a big update PR.

Moosems avatar Jun 27 '23 02:06 Moosems