amend so that the canvas ie pdf area can be scrolled
import tkinter as tk
from tkinter import messagebox
from fpdf import FPDF

class PDFCanvas(tk.Canvas):
    def __init__(self, master=None, width=800, height=600):
        super().__init__(master, width=width, height=height, bg="white")
        self.text_data = []  # Stores (text_id, original_x, original_y, text)
        self.dragging = None
        self.original_width = width  # Original width of the canvas
        self.original_height = height  # Original height of the canvas

        self.bind("<ButtonPress-1>", self.on_click)
        self.bind("<B1-Motion>", self.on_drag)
        self.bind("<ButtonRelease-1>", self.on_release)

    def add_text(self, text):
        safe_text = text.encode('utf-8', 'ignore').decode('utf-8', 'ignore')
        if not safe_text.strip():
            messagebox.showwarning("Input Error", "Please enter some valid text.")
            return

        x, y = 50, 50 + len(self.text_data) * 20
        text_id = self.create_text(x, y, text=safe_text, fill="black", anchor="nw", tags="text")
        self.text_data.append((text_id, x, y, safe_text))

    def on_click(self, event):
        for text_id, x, y, text in self.text_data:
            bbox = self.bbox(text_id)
            if bbox[0] <= event.x <= bbox[2] and bbox[1] <= event.y <= bbox[3]:
                self.dragging = text_id
                self.start_x = event.x
                self.start_y = event.y
                break

    def on_drag(self, event):
        if self.dragging:
            dx = event.x - self.start_x
            dy = event.y - self.start_y
            text_id = self.dragging
            self.move(text_id, dx, dy)
            self.start_x = event.x
            self.start_y = event.y

    def on_release(self, event):
        if self.dragging:
            for index, (text_id, x, y, text) in enumerate(self.text_data):
                if text_id == self.dragging:
                    # Update the original coordinates based on the new position
                    new_x = self.bbox(text_id)[0]
                    new_y = self.bbox(text_id)[1]
                    self.text_data[index] = (text_id, new_x, new_y, text)
                    break
            self.dragging = None

    def set_canvas_size(self, width, height):
        self.original_width = width
        self.original_height = height
        self.config(width=width, height=height)
        self.config(scrollregion=(0, 0, width, height))  # Set scroll region

    def export_to_pdf(self, filename, pdf_width, pdf_height):
        pdf = FPDF()
        pdf.add_page(format=(pdf_width, pdf_height))
        pdf.set_font("Arial", size=12)

        for text_id, x, y, text in self.text_data:
            # Adjust coordinates for PDF export
            pdf.text(x, y, text)

        pdf.output(filename)
        messagebox.showinfo("Success", f"PDF saved as {filename}")


class WYSIWYGApp:
    def __init__(self, root):
        self.root = root
        self.root.title("WYSIWYG Designer for FPDF")

        root.geometry("1200x900")  # Fixed window size

        self.menubar = tk.Menu(root)
        root.config(menu=self.menubar)

        file_menu = tk.Menu(self.menubar, tearoff=0)
        self.menubar.add_cascade(label="File", menu=file_menu)

        paper_sizes = {
            "A4": (210, 297),
            "A5": (148, 210),
            "Letter": (216, 279),
            "Legal": (216, 356),
        }

        paper_menu = tk.Menu(self.menubar, tearoff=0)
        for size_name, (width, height) in paper_sizes.items():
            paper_menu.add_command(
                label=size_name,
                command=lambda w=width, h=height: self.set_paper_size(w, h)
            )
        self.menubar.add_cascade(label="Paper Size", menu=paper_menu)

        # Create a frame to hold the canvas and scrollbar
        self.canvas_frame = tk.Frame(root)
        self.canvas_frame.pack(pady=(10, 0), fill=tk.BOTH, expand=True)

        # Add a vertical scrollbar
        self.scrollbar = tk.Scrollbar(self.canvas_frame, orient=tk.VERTICAL)
        self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        # Create the canvas
        self.canvas = PDFCanvas(master=self.canvas_frame, width=800, height=600)  # Initial size
        self.canvas.pack(side=tk.LEFT)  # Do not allow the canvas to expand

        # Configure the scrollbar to work with the canvas
        self.canvas.config(yscrollcommand=self.scrollbar.set)
        self.scrollbar.config(command=self.canvas.yview)

        # Bind mousewheel event to scroll the canvas
        self.canvas.bind("<MouseWheel>", self.on_mousewheel)

        self.set_paper_size(210, 297)  # Initial A4 size

        self.entry = tk.Entry(root, width=50)
        self.entry.pack()

        self.add_button = tk.Button(root, text="Add Text", command=self.add_text)
        self.add_button.pack()

        self.export_button = tk.Button(root, text="Export to PDF", command=self.export_pdf)
        self.export_button.pack()

    def set_paper_size(self, width_mm, height_mm):
        dpi = 96
        width_px = width_mm / 25.4 * dpi
        height_px = height_mm / 25.4 * dpi

        # Set the original canvas size
        self.canvas.set_canvas_size(width_px, height_px)
        self.pdf_width = width_mm
        self.pdf_height = height_mm

    def on_mousewheel(self, event):
        # Scroll the canvas vertically
        self.canvas.yview_scroll(-1 * (event.delta // 120), "units")

    def add_text(self):
        text = self.entry.get()
        if text:
            self.canvas.add_text(text)
            self.entry.delete(0, tk.END)
        else:
            messagebox.showwarning("Input Error", "Please enter some text.")

    def export_pdf(self):
        filename = "output.pdf"
        self.canvas.export_to_pdf(filename, self.pdf_width, self.pdf_height)


if __name__ == "__main__":
    root = tk.Tk()
    app = WYSIWYGApp(root)
    root.mainloop()