|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: P T
Length: 11855 (0x2e4f)
Types: TextFile
Names: »PagingView.c«
└─⟦8648bda34⟧ Bits:30007244 EUUGD5_II: X11R5
└─⟦87c3ac0e0⟧ »./contrib-3/contrib-3.00«
└─⟦de8ce1454⟧
└─⟦this⟧ »contrib/lib/iv/src/bin/doc/PagingView.c«
/*
* Copyright (c) 1991 Stanford University
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Stanford not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. Stanford makes no representations about
* the suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
* IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* PagingView
*/
#include "PagingView.h"
#include "Command.h"
#include "Document.h"
#include "DocViewer.h"
#include "InsertMarker.h"
#include "PageButton.h"
#include "TextItem.h"
#include "codes.h"
#include "properties.h"
#include <InterViews/arraycomp.h>
#include <InterViews/background.h>
#include <InterViews/composition.h>
#include <InterViews/discretion.h>
#include <InterViews/hit.h>
#include <InterViews/listener.h>
#include <InterViews/lrmarker.h>
#include <InterViews/patch.h>
#include <InterViews/simplecomp.h>
#include <InterViews/strut.h>
#include <InterViews/target.h>
#include <InterViews/texcomp.h>
#include <InterViews/world.h>
#include <OS/math.h>
#include <stdio.h>
#include <string.h>
PagingView::PagingView (
DocumentViewer* viewer, ItemView* parent, TextItem* text, Glyph* pages
) : TextView(viewer, parent, text) {
Document* document = _text->document();
Coord textwidth = document->document_metric("textwidth");
Coord textheight = document->document_metric("textheight");
Coord gutter = document->document_metric("gutter");
Coord format_width = Coord(_text->format_width());
if (format_width == 0) {
format_width = fil;
}
_column_count = long(document->document_metric("columns"));
_columns = new LRComposition(
pages,
new ArrayCompositor(2 * _column_count),
new HStrut(textwidth, 0, 0, 0, 0),
textwidth, 20
);
_lines = new TBComposition(
_columns,
new TeXCompositor(int(document->document_metric("pagepenalty"))),
new Discretionary(
0,
new VStrut(0, textheight, gutter, 0, 0),
new VStrut(0, textheight, 0, 0, 0), nil, nil
),
textheight, _text->item_count() / 30
);
_lines->view(0, 0);
_characters = new LRComposition(
_lines,
new TeXCompositor(int(document->document_metric("linepenalty"))),
nil,
format_width, _text->item_count()
);
_characters->append(_text->document()->character(newpage, 1));
_characters->view(0, 0);
_text_patch = new Patch(_characters);
Glyph* g = _text_patch;
_select_marker = new LRMarker*[_column_count];
Color* ol;
Color* ul;
_viewer->highlight_colors(SELECT_HIGHLIGHT_COLOR, ol, ul);
for (long c = 0; c < _column_count; ++c) {
_select_marker[c] = new LRMarker(g, ol, ul);
g = _select_marker[c];
}
_viewer->highlight_colors(INSERT_HIGHLIGHT_COLOR, ol, ul);
_insert_marker = new InsertMarker(g, ol, ul, _viewer->insert_flash());
_listener->body(_insert_marker);
_listener->button(true, Event::left);
_current_page = 0;
}
PagingView::~PagingView () { }
void PagingView::reshaped () {
update();
}
long PagingView::page_containing (long index) {
return _columns->item(_lines->item(_characters->item(index)));
}
void PagingView::view_page (long page) {
_current_page = page;
long first_column = _columns->beginning_of(page);
long last_column = _columns->end_of(page);
long first_line = _lines->beginning_of(first_column);
long last_line = _lines->end_of(last_column);
long first_char = _characters->beginning_of(first_line);
long last_char = _characters->end_of(last_line);
_lines->view(first_line, last_line);
_characters->view(first_char - 1, last_char + 1);
_text_patch->reallocate();
mark_selection();
}
void PagingView::item_changed (long index, long count) {
Document* document = _text->document();
for (long i = index; i < index + count; ++i) {
Item* item = _text->item(i);
Glyph* g;
if (item == nil) {
g = document->character(_text->item_code(i), _text->item_style(i));
} else {
g = _characters->component(i);
}
g->ref();
_characters->replace(i, nil);
_characters->replace(i, g);
g->unref();
}
TextView::item_changed(index, count);
}
void PagingView::item_replaced (long index, long count) {
Document* document = _text->document();
for (long i = index; i < index + count; ++i) {
Item* item = _text->item(i);
Glyph* g;
if (item == nil) {
g = document->character(_text->item_code(i), _text->item_style(i));
} else {
g = new Target(item->view(this, _viewer), TargetCharacterHit);
}
g->ref();
_characters->replace(i, nil);
_characters->replace(i, g);
g->unref();
}
TextView::item_replaced(index, count);
}
void PagingView::item_inserted (long index, long count) {
Document* document = _text->document();
for (long i = index; i < index + count; ++i) {
Item* item = _text->item(i);
Glyph* g;
if (item == nil) {
g = document->character(_text->item_code(i), _text->item_style(i));
} else {
g = new Target(item->view(this, _viewer), TargetCharacterHit);
}
_characters->insert(i, g);
}
TextView::item_inserted(index, count);
}
void PagingView::item_removed (long index, long count) {
for (long i = index; i < index + count; ++i) {
_characters->remove(index);
}
TextView::item_removed(index, count);
}
long PagingView::index (Coord x, Coord y) {
Hit hit(x, y);
_text_patch->repick(0, hit);
if (hit.any()) {
long result = hit.index(0);
if (hit.depth() > 0) {
result += hit.index(1);
}
return result;
} else {
return -1;
}
}
void PagingView::repair () {
TextView::repair();
_viewer->page_to_view(dot());
}
void PagingView::update () {
_characters->repair();
do {
_text_patch->reallocate();
long count = _columns->count();
for (long i = 0; i < count; ++i) {
long page = _columns->item(i);
Allotment ax, ay;
_columns->allotment(i, Dimension_X, ax);
_columns->allotment(i, Dimension_Y, ay);
Coord l = ax.begin();
Coord r = ax.end();
Coord b = ay.begin();
Coord t = ay.end();
Coord top = _viewer->top_margin(page, l, b, r, t);
Coord bottom = _viewer->bottom_margin(page, l, b, r, t);
_lines->margin(i, top, bottom);
}
} while (!_lines->repair() && !_columns->repair());
_text_patch->reallocate();
mark_selection();
}
void PagingView::mark_selection () {
for (long i = 0; i < _column_count; ++i) {
mark_column(i);
}
mark_insertion();
}
void PagingView::mark_insertion () {
long dot = Math::min(_text->item_count(), _dot);
long dot_line = _characters->item(dot);
long dot_column = _lines->item(dot_line);
long dot_page = _columns->item(dot_column);
if (_active && _dot == _mark && dot_page == _current_page) {
Allotment dot_x, dot_line_y;
_characters->allotment(dot, Dimension_X, dot_x);
_lines->allotment(dot_line, Dimension_Y, dot_line_y);
Coord x = dot_x.begin();
Coord y = dot_line_y.begin();
Coord h = dot_line_y.end() - y;
Coord w = 1;
_insert_marker->mark(x, y, w, h);
} else {
_insert_marker->unmark();
}
}
void PagingView::mark_column (long i) {
long column = _current_page * _column_count + 2 * i;
LRMarker* marker = _select_marker[i];
long dot = Math::min(_dot, _mark);
long mark = Math::max(_dot, _mark);
dot = Math::min(_text->item_count(), dot);
mark = Math::min(_text->item_count(), mark);
long dot_line = _characters->item(dot);
long mark_line = _characters->item(mark);
long dot_column = _lines->item(dot_line);
long mark_column = _lines->item(mark_line);
long topline = _lines->beginning_of(column);
long bottomline = _lines->end_of(column);
if (column < _columns->count() - 1) {
Allotment column_x, bottom_y, top_y;
_columns->allotment(column, Dimension_X, column_x);
_lines->allotment(bottomline, Dimension_Y, bottom_y);
_lines->allotment(topline, Dimension_Y, top_y);
Coord left = column_x.begin();
Coord bottom = bottom_y.begin();
Coord right = column_x.end();
Coord top = top_y.end();
marker->bound(left, bottom, right, top);
}
if (
!_active || _dot == _mark
|| mark_column < column || dot_column > column
) {
marker->unmark();
} else {
Coord x1, y1, h1, x2, y2, h2;
if (dot_column < column) {
Allotment column_x, topline_y;
_columns->allotment(column, Dimension_X, column_x);
_lines->allotment(topline, Dimension_Y, topline_y);
x1 = column_x.begin();
y1 = topline_y.begin();
h1 = topline_y.end() - y1;
} else {
Allotment dot_x, dot_line_y;
_characters->allotment(dot, Dimension_X, dot_x);
_lines->allotment(dot_line, Dimension_Y, dot_line_y);
x1 = dot_x.begin();
y1 = dot_line_y.begin();
h1 = dot_line_y.end() - y1;
}
if (mark_column > column) {
Allotment column_x, bottomline_y;
_columns->allotment(column, Dimension_X, column_x);
_lines->allotment(bottomline, Dimension_Y, bottomline_y);
x2 = column_x.end();
y2 = bottomline_y.begin();
h2 = bottomline_y.end() - y2;
} else {
Allotment mark_x, mark_line_y;
_characters->allotment(mark, Dimension_X, mark_x);
_lines->allotment(mark_line, Dimension_Y, mark_line_y);
x2 = mark_x.begin();
y2 = mark_line_y.begin();
h2 = mark_line_y.end() - y2;
}
marker->mark(x1, y1, h1, x2, y2, h2);
}
}
boolean PagingView::command (const char* command) {
boolean done = false;
if (strncmp(command, "go", 2) == 0) {
long d = Math::min(_dot, _mark);
long m = Math::max(_dot, _mark);
if (strcmp(command+3, "forward_line") == 0) {
dot(_characters->beginning_of(_characters->item(m)+2));
done = true;
} else if (strcmp(command+3, "backward_line") == 0) {
dot(_characters->beginning_of(_characters->item(d)-2));
done = true;
} else if (strcmp(command+3, "forward_page") == 0) {
long dot_column = _lines->item(_characters->item(d));
dot(_characters->beginning_of(_lines->beginning_of(dot_column+2)));
done = true;
} else if (strcmp(command+3, "backward_page") == 0) {
long dot_column = _lines->item(_characters->item(d));
dot(_characters->beginning_of(_lines->beginning_of(dot_column-2)));
done = true;
}
}
if (done) {
return true;
} else {
return TextView::command(command);
}
}