home *** CD-ROM | disk | FTP | other *** search
- =head1 NAME
-
- Mac::Lists - Macintosh Toolbox Interface to List Manager
-
- =head1 SYNOPSIS
-
-
- =head1 DESCRIPTION
-
- Access to Inside Macintosh is essential for proper use of these functions.
- Explanations of terms, processes and procedures are provided there.
- Any attempt to use these functions without guidance can cause severe errors in
- your machine, including corruption of data. B<You have been warned.>
-
- =cut
-
- use strict;
-
- package Mac::Lists;
-
- BEGIN {
- use Exporter ();
- use DynaLoader ();
-
- use vars qw(@ISA @EXPORT);
-
- @ISA = qw(Exporter DynaLoader);
- @EXPORT = qw(
- LNew
- LDispose
- LAddColumn
- LAddRow
- LDelColumn
- LDelRow
- LGetSelect
- LLastClick
- LNextCell
- LSize
- LSetDrawingMode
- LScroll
- LAutoScroll
- LUpdate
- LActivate
- LCellSize
- LClick
- LAddToCell
- LClrCell
- LGetCell
- LRect
- LSetCell
- LSetSelect
- LDraw
-
- lDoVAutoscroll
- lDoHAutoscroll
- lOnlyOne
- lExtendDrag
- lNoDisjoint
- lNoExtend
- lNoRect
- lUseSense
- lNoNilHilite
- lInitMsg
- lDrawMsg
- lHiliteMsg
- lCloseMsg
- );
- }
-
- =head2 Constants
-
- =over 4
-
- =item lDoVAutoscroll
-
- =item lDoHAutoscroll
-
- Flags for C<listFlags>.
-
- =cut
- sub lDoVAutoscroll () { 2; }
- sub lDoHAutoscroll () { 1; }
-
-
- =item lOnlyOne
-
- =item lExtendDrag
-
- =item lNoDisjoint
-
- =item lNoExtend
-
- =item lNoRect
-
- =item lUseSense
-
- =item lNoNilHilite
-
- Flags for C<selFlags>.
-
- =cut
- sub lOnlyOne () { -128; }
- sub lExtendDrag () { 64; }
- sub lNoDisjoint () { 32; }
- sub lNoExtend () { 16; }
- sub lNoRect () { 8; }
- sub lUseSense () { 4; }
- sub lNoNilHilite () { 2; }
-
-
- =item lInitMsg
-
- =item lDrawMsg
-
- =item lHiliteMsg
-
- =item lCloseMsg
-
- =cut
- sub lInitMsg () { 0; }
- sub lDrawMsg () { 1; }
- sub lHiliteMsg () { 2; }
- sub lCloseMsg () { 3; }
-
- =back
-
- =cut
-
- bootstrap Mac::Lists;
-
- =include Lists.xs
-
- =head2 Extension to MacWindow
-
- =over 4
-
- =cut
- package MacWindow;
-
- BEGIN {
- use Carp;
- import Mac::Lists;
- }
-
- =item new_list [CLASS, ] LIST
-
- =item new_list [CLASS, ] rView, dataBounds, cSize, theProc, [, drawIt [, hasGrow [, scrollHoriz [, scrollVert]]]]
-
- Create a new list, attach it to the window, and return it. In the first form,
- registers an existing list. In the second form, calls C<LNew>.
-
- =cut
- sub new_list {
- my($my) = shift @_;
- my($type) = @_;
- my($class,$list);
-
- if (ref($type)) {
- $class = "MacList"
- } else {
- $class = shift @_;
- $type = $_[0];
- }
- if (ref($type) eq "ListHandle") {
- $list = $type;
- } else {
- my @pre_ = splice(@_, 0, 4);
- $list = LNew(@pre_, $my->{port}, @_) or croak "LNew failed";
- }
- $class->new($my, $list);
- }
-
- =back
-
- =head2 MacList - The object interface to a list
-
- MacList is a List Manager list embedded into a pane.
-
- =cut
- package MacList;
-
- BEGIN {
- use Mac::Hooks ();
- use Mac::QuickDraw;
- use Mac::Pane;
- use Mac::Events;
- use Mac::Windows();
- import Mac::Lists;
-
- use vars qw(@ISA);
-
- @ISA = qw(Mac::Pane Mac::Hooks);
- }
-
- =item new WINDOW, CONTROL
-
- Initialize a C<MacList> (which is always created with
- C<MacWindow::new_list>).
-
- =cut
- sub new {
- my($class, $window, $list) = @_;
-
- my(%vars) = (window => $window, list => $list);
-
- my $me = bless \%vars, $class;
-
- $window->add_pane($me);
- $window->add_focusable($me);
-
- $me;
- }
-
- =item dispose
-
- Dispose of the toolbox list.
-
- =cut
- sub dispose {
- my($my) = @_;
- LDispose($my->{list}) if $my->{list};
- delete $my->{list};
- }
-
- =item DESTROY
-
- Destroys the C<MacList>.
-
- =cut
- sub DESTROY {
- dispose(@_);
- }
-
- =item list
-
- Get the toolbox list handle.
-
- =cut
- sub list {
- my($my) = @_;
-
- $my->{list};
- }
-
- =item attach(WINDOW)
-
- Called by MacWindow to indicate that the pane has just been attached.
-
- =cut
- sub attach {
- my($my, $window) = @_;
-
- $window->{lists}->{${$my->{list}}} = $my;
- }
-
- =item detach(WINDOW)
-
- Called by MacWindow to indicate that the pane has just been detached.
-
- =cut
- sub detach {
- my($my, $window) = @_;
-
- delete $window->{lists}->{${$my->{list}}};
- dispose(@_);
- }
-
- =item focus(WINDOW, FOCUS)
-
- Called by MacWindow to indicate that the list has acquired (1) or lost (0) the
- focus.
-
- =cut
- sub focus {
- my($my, $window, $focus) = @_;
- my $list = $my->{list};
-
- LActivate($focus, $list);
-
- $my->callhook("focus", @_) and return;
-
- return unless scalar(@{$window->{focusable}}) > 1;
-
- my $pen = GetPenState;
- my $r = InsetRect $list->bounds, -4, -4;
- PenSize(2,2);
- PenMode($focus ? patOr : patBic);
- FrameRect($r);
- SetPenState($pen);
- }
-
- =item redraw(WINDOW)
-
- Redraw the contents of the pane.
-
- =cut
- sub redraw {
- my($my, $window) = @_;
- my $list = $my->{list};
-
- LUpdate($window->window->visRgn, $list);
-
- my $r = InsetRect $list->bounds, -1, -1;
- FrameRect($r);
-
- $my->callhook("redraw", @_) && return;
-
- return unless $window->has_focus($my) && $window->can_focus;
-
- my $pen = GetPenState;
- $r = InsetRect $list->bounds, -4, -4;
-
- PenSize(2,2);
- FrameRect($r);
- SetPenState($pen);
- }
-
- sub _doselection {
- my($list,$clear) = @_;
-
- my $sel = LGetSelect(1, new Point(0,0), $list);
-
- return
- ($list->dataBounds->botRight, new Point(-1,-1))
- unless $sel;
-
- LSetSelect(0, $sel, $list) if $clear;
-
- my($first,$last) = ($sel, $sel);
-
- while ($sel = LNextCell(1, 1, $sel, $list)) {
- last unless $sel = LGetSelect(1, $sel, $list);
- LSetSelect(0, $sel, $list) if $clear;
- $last = $sel;
- }
-
- return ($first, $last);
- }
-
- sub _selectionrect {
- my($list, $start) = @_;
- my($sel) = new Rect($start->h, $start->v, $start->h, $start->v);
- if (!LGetSelect(0, $start, $list)) {
- return $sel;
- }
- my($cell,$h,$v);
- for ($v = $start->v; $v-- > 0; ) {
- last unless LGetSelect(0, new Point($start->h, $v), $list);
- }
- $sel->top($v+1);
- $v = $start->v+1;
- for ($cell = $start; $cell = LNextCell(0, 1, $cell, $list); ) {
- last unless LGetSelect(0, $cell, $list);
- ++$v;
- }
- $sel->bottom($v);
- LEFT:
- for ($h = $start->h; $h-- > 0; ) {
- for ($v = $sel->top; $v < $sel->bottom; ++$v) {
- last LEFT unless LGetSelect(0, new Point($h, $v), $list);
- }
- }
- $sel->left($h+1);
- RIGHT:
- $h = $start->h+1;
- for ($cell = $start; $cell = LNextCell(1, 0, $cell, $list); ) {
- for ($v = $sel->top; $v < $sel->bottom; ++$v) {
- last RIGHT unless LGetSelect(0, new Point($h, $v), $list);
- }
- ++$h
- }
- $sel->right($h);
-
- return $sel;
- }
-
- sub _selectrect {
- my($list, $r, $select) = @_;
- for my $h ($r->left..$r->right-1) {
- for my $v ($r->top..$r->bottom-1) {
- LSetSelect($select, new Point($h, $v), $list);
- }
- }
- }
-
- =item key(WINDOW, KEY)
-
- Handle a key stroke.
-
- =cut
- sub key {
- my($my, $window, $key) = @_;
- my $list = $my->{list};
-
- $my->callhook("key", @_) and return;
-
- my($h,$v) = (0,0);
- if ($key == 28) { # Left arrow
- $h = -1;
- } elsif ($key == 29) { # Right arrow
- $h = 1;
- } elsif ($key == 30) { # Up arrow
- $v = -1;
- } elsif ($key == 31) { # Down arrow
- $v = 1;
- } else {
- return 0;
- }
- my $extend =
- ($Mac::Events::CurrentEvent->modifiers & shiftKey)
- && !($list->selFlags & lNoExtend);
- my $extreme = $Mac::Events::CurrentEvent->modifiers & cmdKey;
- my ($first,$last) = _doselection($list, !$extend);
- if (!$extend || !$my->{anchoring}) {
- my $mul = $extreme ? 16380 : 1;
- my $sel = ($h < 0 || $v < 0) ? $first : $last;
- $last->h($sel->h + $mul*$h);
- $last->v($sel->v + $mul*$v);
- $last = Mac::Windows::PinRect($list->dataBounds, $last);
- if ($extend) {
- _selectrect(
- $list,
- ($h>0 || $v>0)
- ? new Rect($sel->h, $sel->v, $last->h+1, $last->v+1)
- : new Rect($last->h, $last->v, $sel->h+1, $sel->v+1),
- 1);
- } else {
- LSetSelect(1, $last, $list);
- }
- }
- }
-
- =item click(WINDOW, PT)
-
- Handle a click.
-
- =cut
- sub click {
- my($my, $window, $pt) = @_;
- my($res);
-
- ($res = $my->callhook("click", @_)) and return $res;
-
- if (LClick($pt, $Mac::Events::CurrentEvent->modifiers, $my->{list})) {
- $my->hit($window);
- }
- return PtInRect($pt, $my->{list}->bounds);
- }
-
- =item hit(WINDOW)
-
- Handle a double click.
-
- =cut
- sub hit {
- defined($_[0]->callhook("hit", @_)) and return;
- }
-
- =item get H, V
-
- =item get PT
-
- Get the list data for a cell.
-
- =cut
- sub get {
- my($my) = shift @_;
- my($cell) = ref($_[0]) ? shift @_ : new Point(splice(@_, 0, 2));
-
- LGetCell($cell, $my->{list});
- }
-
- =item set H, V, DATA
-
- =item set PT, DATA
-
- Set the list data for a cell.
-
- =cut
- sub set {
- my($my) = shift @_;
- my($cell) = ref($_[0]) ? shift @_ : new Point(splice(@_, 0, 2));
- my($data) = @_;
-
- LSetCell($data, $cell, $my->{list});
- }
-
- =head1 BUGS/LIMITATIONS
-
- =head1 FILES
-
- =head1 AUTHOR(S)
-
- Matthias Ulrich Neeracher <neeri@iis.ee.ethz.ch>
-
- =cut
-
- 1;
-
- __END__
-