class viewer {}

proc viewer::viewer {this parentPath args} composite {
    [new frame $parentPath] $args
} {
    composite::manage $this\
        [new text $widget::($this,path) -state disabled -wrap none] text\
        [new scrollbar $widget::($this,path)] vertical\
        [new scrollbar $widget::($this,path) -orient horizontal] horizontal

    widget::configure $composite::($this,text)\
        -yscrollcommand "$composite::($this,vertical,path) set"\
        -xscrollcommand "$composite::($this,horizontal,path) set"
    set textPath $composite::($this,text,path)
    widget::configure $composite::($this,vertical) -command "$textPath yview"
    widget::configure $composite::($this,horizontal) -command "$textPath xview"

    grid $textPath -sticky nsew
    grid $composite::($this,vertical,path) -column 1 -row 0 -sticky nsew
    grid $composite::($this,horizontal,path) -row 1 -sticky nsew
    grid rowconfigure $widget::($this,path) 0 -weight 1
    grid columnconfigure $widget::($this,path) 0 -weight 1

    composite::complete $this
}

proc viewer::~viewer {this} {}

proc viewer::options {this} {
    return {{-file {} {}} {-text {} {}}}
}

proc viewer::set-text {this text} {
    widget::configure $composite::($this,text) -state normal
    $composite::($this,text,path) delete 1.0 end
    $composite::($this,text,path) insert 1.0 $text
    widget::configure $composite::($this,text) -state disabled
}

proc viewer::set-file {this name} {
    if {[string length $name]==0} return
    set file [open $name]
    set-text $this [read $file]
    close $file
}
