//[of]:description //[c]A single pane (or a decorated text view) //[c] //[c]A code browser view wraps a text view, it adds a title, a border //[c]and a left margin. //[cf] //[of]:license //[c] Code Browser - a folding text editor for programmers //[c] Copyright (C) 2003-07 Marc Kerbiquet //[c] //[c] This program is free software; you can redistribute it and/or modify //[c] it under the terms of the GNU General Public License as published by //[c] the Free Software Foundation; either version 2 of the License, or //[c] (at your option) any later version. //[c] //[c] This program is distributed in the hope that it will be useful, //[c] but WITHOUT ANY WARRANTY; without even the implied warranty of //[c] MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //[c] GNU General Public License for more details. //[c] //[c] You should have received a copy of the GNU General Public License //[c] along with this program; if not, write to the Free Software //[c] Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //[cf] //[of]:imports import "base/types" import "base/memory-allocator" import "base/memory" import "text/string" import "text/string-buffer" import "swift" //[c] import "editor/text-model" import "editor/text-view" //[c] import "application/code-browser-application" //[cf] //[of]:definition public struct code browser view : local container box private text view : text view vertical scrollbar : scrollbar horizontal scrollbar : scrollbar title bar font : font title : string page number : string // This flag prevent reentrant notif // when the page changes ignore scroll event : bool title height: int use horizontal scrollbar : bool virtual width : int end //[c] public struct code browser view class : local container box class end //[cf] //[of]:contants equ margin between title and page = 8 equ border size = 1 equ margin size = 4 //[cf] //[c] //[of]:instance creation //[of]:new code browser view public func new code browser view ( parent: box, font: font, cf: clipboard format, use horizontal scrollbar: bool, virtual width: int) def m = allocate memory ( sizeof local code browser view) : code browser view initialize ( m, parent, font, cf, use horizontal scrollbar, virtual width) return m end //[cf] //[cf] //[of]:accessing //[of]:folder //[c]Returns the current edited folder //[c] public func folder (m: code browser view) return text (text view (m)) end //[cf] //[of]:view //[c]Returns the text view of the page //[c] public equ view (m: code browser view) = text view (m) //[cf] //[of]:format //[c]Returns the text view of the page //[c] public func format (m: code browser view) return format (text view (m)) end //[cf] //[c] //[of]:set title //[c]Changes the title //[c] public func set title (m: code browser view, title: string, page number: string) delete (title (m)) delete (page number (m)) title (m) = new string (title) page number (m) = new string (page number) invalidate (m) end //[cf] //[of]:set title font //[c]Changes the font of the title bar //[c] public func set title font (m: code browser view, font: font) title bar font (m) = font def canvas := canvas (m) set font (canvas, font) title height (m) = height (canvas) release (canvas) invalidate (m) end //[cf] //[of]:set format //[c]Changes the format //[c] public func set format (m: code browser view, f: text view format) // apply the new format to the text view set format (text view (m), f) end //[cf] //[of]:reset format //[c]Changes the format //[c] public func reset format (m: code browser view, f: text view format) // apply the new format to the text view reset format (text view (m), f) end //[cf] //[of]:set view visible public func set view visible (m: code browser view, visible: bool) set visible (vertical scrollbar (m), visible) set visible (horizontal scrollbar (m), visible && use horizontal scrollbar (m)) set visible (text view (m), visible) invalidate min size (m) end //[cf] //[cf] //[of]:testing //[of]:is view visible //[c]Test the visibility of the view //[c] public func is view visible (m: code browser view) return is visible (text view (m)) end //[cf] //[cf] //[c] //[of]:restricted //[of]:code browser view class private def initialized = false private def the code browser view class : local code browser view class //[c] public func code browser view class def c = the code browser view class if ~ initialized initialized = true copy (c, container box class) mem size (c) = sizeof local code browser view class release (c) = ^actual release (code browser view) on child event (c) = ^handle child event (code browser view, box, event) on size (c) = ^handle size (code browser view) on paint (c) = ^handle paint (code browser view, canvas, rectangle) compute min size (c) = ^actual compute min size (code browser view) adjust (c) = ^actual adjust (code browser view) end return c end //[cf] //[of]:initialize public func initialize ( m: code browser view, parent: box, title bar font: font, cf structured text : clipboard format, use horizontal scrollbar: bool, virtual width: int) // initialize container initialize (super (m), parent, true) class (m) = code browser view class use horizontal scrollbar (m) = use horizontal scrollbar virtual width (m) = virtual width ignore scroll event (m) = false vertical scrollbar (m) = new scrollbar (m, sb vertical) horizontal scrollbar (m) = new scrollbar (m, sb horizontal) text view (m) = new text view (m) set title font (m, title bar font) title (m) = empty string page number (m) = empty string // initialize view set structured text clipboard format (view (m), cf structured text) end //[cf] //[c] //[of]:handle child event public func handle child event (m: code browser view, src: box, e: event) def t = type (e) if t == value changed event type || t == page changed event type update scrollbar (m) elsif t == scroll event type if ~ ignore scroll event (m) def pos = pos (e : scroll event) def view = view (m) if src == vertical scrollbar (m) move page (view, add (text view position (view, 0, x (page (view))), pos)) else def page position := page view position (view) x (page position) = pos move page (view, page position) end set focus (view) end return true end return handle child event (super (m), src, e) end //[cf] //[of]:handle size public func handle size (m: code browser view) layout (m) update scrollbar (m) end //[cf] //[of]:handle paint public func handle paint (m: code browser view, c: canvas, clip: rectangle) equ black = 0:d def client rect = client rect (m) def r : local rectangle x (r) = x (client rect) y (r) = y (client rect) w (r) = w (client rect) h (r) = h (client rect) if ~ is view visible (m) def color = workspace color (format (m)) fill rectangle (c, r, color) return end // Draw page def color = comment back color (format (m)) fill rectangle (c, r, color) // Draw separator color = black x (r) = x (client rect) y (r) = y (client rect) + margin size * 2 + title height (m) w (r) = w (client rect) h (r) = border size fill rectangle (c, r, color) // Print title set font (c, title bar font (m)) title rectangle (m, r) color = comment back color (format (m)) set back color (c, color) set text color (c, comment fore color (format (m))) def x = x (r) def w = w (r) // Print page number def u = page number (m) def wr = text width (c, u, size (u)) def xr = max (0, x + w - wr) text out (c, xr, y (r), wr, h (r), u, size (u)) // Print margin wr = margin between title and page xr = max (0, xr - wr) def margin rect := rectangle (xr, y (r), wr, h (r)) // Print title w = max (0, xr - x (r)) text out (c, x(r), y(r), w, h(r), title (m), size (title (m))) def hs = horizontal scrollbar (m) def vs = vertical scrollbar (m) def sh = min height (hs) def sw = min width (vs) if is visible (hs) && is visible (vs) fill rectangle ( c, rectangle (w (client rect) - sw, h (client rect) - sh, sw, sh), label background (style (m))) end end //[c] //[of]:title rectangle func title rectangle (m: code browser view, return r: rectangle) def c = client rect (m) x (r) = c.x + margin size y (r) = c.y + margin size w (r) = c.w - margin size * 2 h (r) = title height (m) end //[cf] //[cf] //[of]:actual adjust public func actual adjust (m: code browser view) layout (m) update scrollbar (m) end //[cf] //[of]:actual compute min size public func actual compute min size (m: code browser view) def a: local area def canvas := canvas (m) set font (canvas, title bar font (m)) text extent (canvas, "X", 1, a) release (canvas) def view = text view (m) def vs = vertical scrollbar (m) def hs = horizontal scrollbar (m) def w = min width (view) + min width (vs) + 2 * margin size def h = min height (view) + min height (vs) + h (a) + 3 * margin size + border size set min size (m, w, h) end //[cf] //[of]:actual release public func actual release (m: code browser view) actual release (super (m)) delete (title (m)) delete (page number (m)) end //[cf] //[cf] //[of]:private //[of]:layout public func layout (m: code browser view) def c = client rect (m) def x = c.x + margin size def y = c.y + border size + margin size * 3 + title height (m) def w = c.w - margin size * 2 def h = c.h - y def hs = horizontal scrollbar (m) def vs = vertical scrollbar (m) def scrollbar height = min height (hs) def scrollbar width = min width (vs) if is visible (hs) h -= scrollbar height end if is visible (vs) w -= scrollbar width end move (hs, rectangle (c.x, y + h, w + margin size * 2, scrollbar height)) move (vs, rectangle (x + w + margin size, y, scrollbar width, h)) if w < 0 w = 0 end if h < 0 h = 0 end move (text view (m), rectangle (x, y, w, h)) invalidate (m) end //[cf] //[of]:update scrollbar private func update scrollbar (m: code browser view) def view = view (m) def page size = page height (view) if page size == 0 return end def text = text (view) if is nil (text) return end ignore scroll event (m) = true def page = page (view) // vertical scrollbar def vs = vertical scrollbar (m) def document size = number of sublines (view) - 1 def show scrollbar = page size <= document size if show scrollbar <> is visible (vs) set visible (vs, show scrollbar) layout (m) end if is visible (vs) def line = convert line to logical line (view, line number (page), subline (page)) set scroll info ( vs, 0, document size, page size, line) end // horizontal scrollbar if use horizontal scrollbar (m) set scroll info ( horizontal scrollbar (m), 0, (is view visible (m) -> virtual width (m), 0), width (client rect (view)), x (page)) end ignore scroll event (m) = false end //[cf] //[cf]