home *** CD-ROM | disk | FTP | other *** search
- // Zinc Interface Library - SCROLL.CPP
- // COPYRIGHT (C) 1990, 1991. All Rights Reserved.
- // Zinc Software Incorporated. Pleasant Grove, Utah USA
-
- #include "ui_win.hpp"
-
- // Special button identifications - order is important.
- const int TOTAL_BUTTONS = 5;
- const int TOP_BUTTON = 0;
- const int LEFT_BUTTON = 0;
- const int BOTTOM_BUTTON = 1;
- const int RIGHT_BUTTON = 1;
- const int MIDDLE_BUTTON = 2;
- const int TOP_REGION = 3;
- const int LEFT_REGION = 3;
- const int BOTTOM_REGION = 4;
- const int RIGHT_REGION = 4;
-
- void UIW_SCROLL_BAR::UserFunction(void *data, UI_EVENT &event)
- {
- UIW_BUTTON *button = (UIW_BUTTON *)data;
- UIW_SCROLL_BAR *scroll = (UIW_SCROLL_BAR *)button->parent;
- int current = scroll->current;
- if (button->value == TOP_BUTTON)
- current--;
- else if (button->value == BOTTOM_BUTTON)
- current++;
- else if (button->value == MIDDLE_BUTTON)
- {
- int size = scroll->display->isText ? 1 : scroll->display->cellWidth * 2;
- long numerator = (long)(button->relative.top - scroll->button[TOP_BUTTON]->true.bottom) * (long)scroll->maximum;
- long denominator = (long)(scroll->button[BOTTOM_BUTTON]->true.top - scroll->button[TOP_BUTTON]->true.bottom - size);
- if (denominator > 0)
- current = (int)(numerator / denominator);
- }
- else
- {
- event.type = (button->value == TOP_REGION) ? L_PGUP : L_PGDN;
- if (scroll->Next())
- scroll->Next()->Event(event);
- return;
- }
-
- if (current < 0)
- current = 0;
- else if (current > scroll->maximum)
- current = scroll->maximum;
-
- for (UI_WINDOW_OBJECT *object = scroll->Next(); object; object = object->Next())
- if (!FlagSet(object->woAdvancedFlags, WOAF_NON_CURRENT))
- break;
- if (object && current != scroll->current)
- {
- event.type = S_SCROLL_VERTICAL;
- event.scroll.delta = scroll->current - current;
- object->eventManager->Put(event, Q_BEGIN);
- if (!FlagSet(object->woStatus, WOS_CURRENT))
- {
- event.type = L_BEGIN_SELECT;
- event.position.column = object->true.left;
- event.position.line = object->true.top;
- object->eventManager->Put(event, Q_BEGIN);
- }
- }
- }
-
- UIW_SCROLL_BAR::UIW_SCROLL_BAR(int left, int top, int width, int height,
- USHORT _sbFlags, USHORT _woFlags) :
- UIW_WINDOW(left, top, width, height, _woFlags, WOAF_NON_CURRENT),
- sbFlags(_sbFlags), current(0), showing(0), maximum(0)
- {
- // Initialize the slide information.
- windowID[0] = ID_SCROLL_BAR;
- windowID[1] = ID_WINDOW;
- search.type = ID_SCROLL_BAR;
-
- // Check for the corner scroll-bar
- if (!FlagSet(sbFlags, SBF_VERTICAL | SBF_HORIZONTAL))
- {
- button[0] = new UIW_BUTTON(0, 0, 0, "", BTF_NO_TOGGLE | BTF_NO_3D,
- WOF_NON_FIELD_REGION | WOF_NON_SELECTABLE);
- woFlags |= WOF_NON_SELECTABLE;
- UI_LIST::Add(button[0]);
- return;
- }
-
- char *vertical[5] = { "\036", "\037", "\007", NULL, NULL };
- char *horizontal[5] = { "\021", "\020", "\007", NULL, NULL };
- for (int i = 0; i < TOTAL_BUTTONS; i++)
- {
- USHORT flags = (i >= TOP_REGION) ?
- BTF_NO_TOGGLE | BTF_NO_3D : BTF_NO_TOGGLE;
- button[i] = FlagSet(_sbFlags, SBF_VERTICAL) ?
- new UIW_BUTTON(0, 0, 0, vertical[i], flags,
- WOF_JUSTIFY_CENTER | WOF_NON_FIELD_REGION,
- UIW_SCROLL_BAR::UserFunction, i) :
- new UIW_BUTTON(0, 0, 0, horizontal[i], BTF_NO_TOGGLE | flags,
- WOF_JUSTIFY_CENTER | WOF_NON_FIELD_REGION,
- UIW_SCROLL_BAR::UserFunction, i);
- if (i >= TOP_REGION)
- button[i]->WindowID(0, ID_SCROLL_BAR);
- button[i]->woAdvancedFlags |= WOAF_NON_CURRENT;
- UI_LIST::Add(button[i]);
- }
- }
-
- UIW_SCROLL_BAR::Event(const UI_EVENT &event)
- {
- static int deltaLine;
-
- // Switch on the event type.
- int ccode = UI_WINDOW_OBJECT::LogicalEvent(event, ID_SCROLL_BAR);
- switch (ccode)
- {
- case S_CREATE:
- case S_SIZE:
- // Compute the scroll bar position.
- display->RegionConvert(relative, &woStatus, WOS_GRAPHICS);
- if (!FlagSet(woFlags, WOF_NON_FIELD_REGION) && FlagSet(sbFlags, SBF_VERTICAL))
- relative.right = display->isText ?
- relative.left : relative.left + 2 * display->cellWidth - 1;
- else if (!FlagSet(woFlags, WOF_NON_FIELD_REGION) && FlagSet(sbFlags, SBF_HORIZONTAL))
- relative.bottom = display->isText ?
- relative.top : relative.top + 2 * display->cellWidth - 1;
- UI_WINDOW_OBJECT::RegionMax(FlagSet(sbFlags, SBF_VERTICAL) ? TRUE : FALSE);
- int startButton = TOP_BUTTON;
- int endButton = (ccode == S_CREATE) ? BOTTOM_BUTTON : BOTTOM_REGION;
- if (FlagSet(sbFlags, SBF_VERTICAL))
- VerticalCompute(startButton, endButton);
- else if (FlagSet(sbFlags, SBF_HORIZONTAL))
- HorizontalCompute(startButton, endButton);
- else
- CornerCompute();
- break;
-
- case S_SCROLL_VERTICAL:
- case S_SCROLL_HORIZONTAL:
- case S_SCROLL_VERTICAL_SET:
- case S_SCROLL_HORIZONTAL_SET:
- if ((ccode == S_SCROLL_VERTICAL_SET && FlagSet(sbFlags, SBF_VERTICAL)) ||
- (ccode == S_SCROLL_HORIZONTAL_SET && FlagSet(sbFlags, SBF_HORIZONTAL)))
- {
- showing = event.scroll.showing;
- maximum = event.scroll.maximum;
- current = event.scroll.current;
- if (current > maximum)
- current = maximum;
- }
- else if ((ccode == S_SCROLL_VERTICAL && FlagSet(sbFlags, SBF_VERTICAL)) ||
- (ccode == S_SCROLL_HORIZONTAL && FlagSet(sbFlags, SBF_HORIZONTAL)))
- {
- current -= event.scroll.delta;
- if (current < 0)
- current = 0;
- else if (current > maximum)
- current = maximum;
- }
- else if (previous)
- {
- Previous()->Event(event);
- break;
- }
- if (FlagSet(sbFlags, SBF_VERTICAL))
- VerticalCompute(MIDDLE_BUTTON, BOTTOM_REGION);
- else if (FlagSet(sbFlags, SBF_HORIZONTAL))
- HorizontalCompute(MIDDLE_BUTTON, RIGHT_REGION);
- break;
-
- case L_BEGIN_SELECT:
- case L_CONTINUE_SELECT:
- case L_END_SELECT:
- if (FlagSet(sbFlags, SBF_CORNER) || FlagSet(woAdvancedStatus, WOAS_TOO_SMALL))
- break;
- UIW_BUTTON *middle = button[MIDDLE_BUTTON];
- if (ccode == L_BEGIN_SELECT && middle->Overlap(event.position) &&
- !FlagSet(middle->woStatus, WOS_CURRENT) &&
- !FlagSet(middle->woAdvancedStatus, WOAS_INVALID_REGION))
- {
- middle->woStatus |= WOS_CURRENT;
- middle->relative = middle->true;
- if (!display->isText)
- display->Rectangle(screenID, middle->relative, _xorPalette, 1, FALSE, TRUE);
- deltaLine = event.position.line - middle->true.top;
- }
- else if (ccode == L_CONTINUE_SELECT &&
- FlagSet(middle->woStatus, WOS_CURRENT))
- {
- int deltaY = 0;
- if (FlagSet(sbFlags, SBF_VERTICAL))
- {
- deltaY = event.position.line - middle->true.top - deltaLine;
- if (middle->true.top + deltaY < button[TOP_BUTTON]->true.bottom)
- deltaY = button[TOP_BUTTON]->true.bottom - middle->true.top;
- else if (middle->true.bottom + deltaY > button[BOTTOM_BUTTON]->true.top)
- deltaY = button[BOTTOM_BUTTON]->true.top - middle->true.bottom;
- }
- UI_REGION region = middle->true;
- region.top += deltaY;
- region.bottom += deltaY;
- if (!display->isText)
- display->RectangleXORDiff(middle->relative, region);
- middle->relative = region;
- }
- else if (ccode == L_END_SELECT && FlagSet(middle->woStatus, WOS_CURRENT))
- {
- if (!display->isText)
- display->Rectangle(screenID, middle->relative, _xorPalette, 1, FALSE, TRUE);
- UI_EVENT tEvent = event;
- UIW_SCROLL_BAR::UserFunction(middle, tEvent);
- middle->woStatus &= ~WOS_CURRENT;
- }
- else
- UIW_WINDOW::Event(event);
- break;
-
- default:
- ccode = UIW_WINDOW::Event(event);
- break;
- }
-
- // Return the event control code.
- return (ccode);
- }
-
- void *UIW_SCROLL_BAR::Information(INFORMATION_REQUEST request, void *data)
- {
- if (request == GET_NUMBERID_OBJECT || request == GET_STRINGID_OBJECT ||
- request == PRINT_INFORMATION)
- return (UIW_WINDOW::Information(request, data));
- else
- return (UI_WINDOW_OBJECT::Information(request, data));
- }
-
- void UIW_SCROLL_BAR::CornerCompute()
- {
- int size = display->cellWidth * 2;
- if (true.left < true.right - size + 1)
- true.left = true.right - size + 1;
- if (true.top < true.bottom - size + 1)
- true.top = true.bottom - size + 1;
-
- UIW_BUTTON *tButton = button[0];
- tButton->InformationSet(screenID, display, eventManager,
- windowManager, paletteMapTable, this);
- UI_EVENT event;
- event.type = S_CREATE;
- tButton->Event(event);
- }
-
- void UIW_SCROLL_BAR::HorizontalCompute(int startButton, int endButton)
- {
- int size = display->isText ? display->cellWidth : display->cellWidth * 2;
- if (FlagSet(woFlags, WOF_NON_FIELD_REGION) && true.top < true.bottom - size + 1)
- true.top = true.bottom - size + 1;
- if (size > (true.right - true.left) / 2)
- size = (true.right - true.left) / 2;
- for (int i = startButton; i <= endButton; i++)
- {
- UIW_BUTTON *tButton = button[i];
- tButton->InformationSet(screenID, display, eventManager,
- windowManager, paletteMapTable, this);
- UI_EVENT event;
- event.type = S_CREATE;
- tButton->Event(event);
- if (i == LEFT_BUTTON)
- tButton->true.right = tButton->true.left + size - 1;
- else if (i == RIGHT_BUTTON)
- tButton->true.left = tButton->true.right - size + 1;
- else if (i == MIDDLE_BUTTON && tButton->true.right - tButton->true.left > size)
- {
- if (maximum <= 0)
- maximum = showing = current = 1;
- int width = tButton->true.right - tButton->true.left;
- int tSize = FlagSet(sbFlags, SBF_SIZE_MIDDLE) ?
- size + (int)((long)(width - size) * showing / maximum) :
- size;
- tButton->true.left += (int)((long)(width - tSize) * current / maximum);
- tButton->true.right = tButton->true.left + tSize;
- }
- if (tButton->true.left >= tButton->true.right ||
- (i == LEFT_REGION && tButton->true.left > button[MIDDLE_BUTTON]->true.right))
- tButton->woAdvancedStatus |= WOAS_INVALID_REGION;
- else if (endButton != RIGHT_BUTTON && !FlagSet(woAdvancedStatus, WOAS_INVALID_REGION))
- {
- event.type = S_DISPLAY_ACTIVE;
- event.region = tButton->true;
- tButton->Event(event);
- }
- }
- }
-
- void UIW_SCROLL_BAR::VerticalCompute(int startButton, int endButton)
- {
- int size = display->isText ? display->cellWidth : display->cellWidth * 2;
- if (FlagSet(woFlags, WOF_NON_FIELD_REGION) && true.left < true.right - size + 1)
- true.left = true.right - size + 1;
- if (size > (true.bottom - true.top) / 2)
- size = (true.bottom - true.top) / 2;
- for (int i = startButton; i <= endButton; i++)
- {
- UIW_BUTTON *tButton = button[i];
- tButton->InformationSet(screenID, display, eventManager,
- windowManager, paletteMapTable, this);
- UI_EVENT event;
- event.type = S_CREATE;
- tButton->Event(event);
- if (i == TOP_BUTTON)
- tButton->true.bottom = tButton->true.top + size - 1;
- else if (i == BOTTOM_BUTTON)
- tButton->true.top = tButton->true.bottom - size + 1;
- else if (i == MIDDLE_BUTTON && tButton->true.bottom - tButton->true.top > size)
- {
- if (maximum <= 0)
- maximum = showing = current = 1;
- int height = tButton->true.bottom - tButton->true.top;
- int tSize = FlagSet(sbFlags, SBF_SIZE_MIDDLE) ?
- size + (int)((long)(height - size) * showing / maximum) :
- size;
- tButton->true.top += (int)((long)(height - tSize) * current / maximum);
- tButton->true.bottom = tButton->true.top + tSize;
- }
- if (tButton->true.top > tButton->true.bottom ||
- (i == TOP_REGION && tButton->true.top > button[MIDDLE_BUTTON]->true.bottom))
- tButton->woAdvancedStatus |= WOAS_INVALID_REGION;
- else if (endButton != BOTTOM_BUTTON && !FlagSet(woAdvancedStatus, WOAS_INVALID_REGION))
- {
- event.type = S_DISPLAY_ACTIVE;
- event.region = tButton->true;
- tButton->Event(event);
- }
- }
- }
-
- #ifdef ZIL_LOAD
- UIW_SCROLL_BAR::UIW_SCROLL_BAR(const char *name, UI_STORAGE *file, USHORT loadFlags) :
- UIW_WINDOW(name, file, loadFlags | L_SUB_LEVEL),
- current(0), showing(0), maximum(0)
- {
- windowID[0] = ID_SCROLL_BAR;
- windowID[1] = ID_WINDOW;
-
- if (!file)
- file = _storage;
- file->Load(&sbFlags);
- int i = 0;
- for (UI_WINDOW_OBJECT *object = First(); object; object = object->Next())
- {
- if (i >= TOP_REGION)
- object->WindowID(0, ID_SCROLL_BAR);
- button[i++] = (UIW_BUTTON *)object;
- }
- if (!FlagSet(loadFlags, L_SUB_LEVEL) && FlagSet(file->stStatus, STS_TEMPORARY))
- delete file;
- }
- #endif
-
- #ifdef ZIL_STORE
- void UIW_SCROLL_BAR::Store(const char *name, UI_STORAGE *file, USHORT storeFlags)
- {
- UIW_WINDOW::Store(name, file, storeFlags | S_SUB_LEVEL);
- file->Store(sbFlags);
- if (!FlagSet(storeFlags, S_SUB_LEVEL))
- file->ObjectSize(name, search);
- }
- #endif
-