/* g_text.cpp * * Copyright (c) 1994-1996, Marko Macek * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. * */ #include #include #include #include #include #include #include "console.h" #include "gui.h" #include "c_mode.h" #include "c_color.h" #if defined(_DEBUG) && defined(MSVC) && defined(MSVCDEBUG) #include #define new new( _CLIENT_BLOCK, __FILE__, __LINE__) #endif //_DEBUG && MSVC && MSVCDEBUG int ShowVScroll = 1; int ShowHScroll = 1; int ShowMenuBar = 1; int ShowToolBar = 0; unsigned long HaveGUIDialogs = 0; // no gui dialogs in text gui GFrame *frames = 0; GUI *gui = 0; GView *MouseCapture = 0; GView *FocusCapture = 0; TEvent NextEvent = { 0 }; #define sfFocus 1 class UpMenu; extern int ExecMainMenu(TEvent &E, char sub); extern int ExecVertMenu(int x, int y, int id, TEvent &E, UpMenu *up); class GViewPeer { public: GView *View; int wX, wY, wW, wH, wState; int cX, cY, cVisible, cStart, cEnd; int sbVstart, sbVamount, sbVtotal, sbVupdate; int sbHstart, sbHamount, sbHtotal, sbHupdate; int SbVBegin, SbVEnd, SbHBegin, SbHEnd; GViewPeer(GView *view, int XSize, int YSize); ~GViewPeer(); int ConPutBox(int X, int Y, int W, int H, PCell Cell); int ConGetBox(int X, int Y, int W, int H, PCell Cell); int ConPutLine(int X, int Y, int W, int H, PCell Cell); int ConSetBox(int X, int Y, int W, int H, TCell Cell); int ConScroll(int Way, int X, int Y, int W, int H, TAttr Fill, int Count); int ConSetSize(int X, int Y); int ConQuerySize(int *X, int *Y); int ConSetCursorPos(int X, int Y); int ConQueryCursorPos(int *X, int *Y); int ConShowCursor(); int ConHideCursor(); int ConCursorVisible(); int ConSetCursorSize(int Start, int End); int CaptureMouse(int grab); int CaptureFocus(int grab); int QuerySbVPos(); int SetSbVPos(int Start, int Amount, int Total); int SetSbHPos(int Start, int Amount, int Total); int ExpandHeight(int DeltaY); int DrawScrollBar(); int UpdateCursor(); }; class GFramePeer { public: int fW, fH; GFrame *Frame; GFramePeer(GFrame *aFrame, int Width, int Height); ~GFramePeer(); int ConSetTitle(char *Title, char *STitle); int ConGetTitle(char *Title, int MaxLen, char *STitle, int SMaxLen); int ConSetSize(int X, int Y); int ConQuerySize(int *X, int *Y); }; /////////////////////////////////////////////////////////////////////////// GViewPeer::GViewPeer(GView *view, int XSize, int YSize) { View = view; wX = 0; wY = 0; wW = XSize; wH = YSize; sbVtotal = 0; sbVstart = 0; sbVamount = 0; sbVupdate = 1; sbHtotal = 0; sbHstart = 0; sbHamount = 0; sbHupdate = 1; wState = 0; cVisible = 1; cStart = 0; // % cEnd = 100; cX = cY = 0; } GViewPeer::~GViewPeer() { if (MouseCapture == View) MouseCapture = 0; if (FocusCapture == View) FocusCapture = 0; } int GViewPeer::ConPutBox(int X, int Y, int W, int H, PCell Cell) { return ::ConPutBox(X + wX, Y + wY, W, H, Cell); } int GViewPeer::ConGetBox(int X, int Y, int W, int H, PCell Cell) { return ::ConGetBox(X + wX, Y + wY, W, H, Cell); } int GViewPeer::ConPutLine(int X, int Y, int W, int H, PCell Cell) { return ::ConPutLine(X + wX, Y + wY, W, H, Cell); } int GViewPeer::ConSetBox(int X, int Y, int W, int H, TCell Cell) { return ::ConSetBox(X + wX, Y + wY, W, H, Cell); } int GViewPeer::ConScroll(int Way, int X, int Y, int W, int H, TAttr Fill, int Count) { return ::ConScroll(Way, X + wX, Y + wY, W, H, Fill, Count); } int GViewPeer::ConSetSize(int X, int Y) { wW = X; wH = Y; return 1; } int GViewPeer::ConQuerySize(int *X, int *Y) { if (X) *X = wW; if (Y) *Y = wH; return 1; } int GViewPeer::ConSetCursorPos(int X, int Y) { if (X < 0) X = 0; if (X >= wW) X = wW - 1; if (Y < 0) Y = 0; if (Y >= wH) Y = wH - 1; cX = X; cY = Y; if (wState & sfFocus) return ::ConSetCursorPos(cX + wX, cY + wY); else return 1; } int GViewPeer::ConQueryCursorPos(int *X, int *Y) { if (X) *X = cX; if (Y) *Y = cY; return 1; } int GViewPeer::ConShowCursor() { cVisible = 1; if (wState & sfFocus) return ::ConShowCursor(); else return 1; } int GViewPeer::ConHideCursor() { cVisible = 0; if (wState & sfFocus) return ::ConHideCursor(); else return 1; } int GViewPeer::ConCursorVisible() { return cVisible; } int GViewPeer::ConSetCursorSize(int Start, int End) { cStart = Start; cEnd = End; if (wState & sfFocus) return ::ConSetCursorSize(Start, End); else return 1; } int GViewPeer::CaptureMouse(int grab) { if (MouseCapture == 0) { if (grab) MouseCapture = View; else return 0; } else { if (grab || MouseCapture != View) return 0; else MouseCapture = 0; } return 1; } int GViewPeer::CaptureFocus(int grab) { if (FocusCapture == 0) { if (grab) FocusCapture = View; else return 0; } else { if (grab || FocusCapture != View) return 0; else FocusCapture = 0; } return 1; } int GViewPeer::ExpandHeight(int DeltaY) { if (View->Parent->Top == View->Next) return -1; if (DeltaY + wH < 3) DeltaY = - (wH - 3); if (View->Next->Peer->wH - DeltaY < 3) DeltaY = View->Next->Peer->wH - 3; View->Peer->ConSetSize(wW, wH + DeltaY); View->Next->Peer->wY += DeltaY; View->Next->Peer->ConSetSize(View->Next->Peer->wW, View->Next->Peer->wH - DeltaY); View->Resize(View->Peer->wW, View->Peer->wH); View->Next->Resize(View->Next->Peer->wW, View->Next->Peer->wH); return 0; } int GViewPeer::QuerySbVPos() { return sbVstart; } int GViewPeer::SetSbVPos(int Start, int Amount, int Total) { if (sbVstart != Start || sbVamount != Amount || sbVtotal != Total) { sbVstart = Start; sbVamount = Amount; sbVtotal = Total; sbVupdate = 1; // DrawScrollBar(); } return 1; } int GViewPeer::SetSbHPos(int Start, int Amount, int Total) { if (sbHstart != Start || sbHamount != Amount || sbHtotal != Total) { sbHstart = Start; sbHamount = Amount; sbHtotal = Total; sbHupdate = 1; // DrawScrollBar(); } return 1; } int GViewPeer::UpdateCursor() { ConSetCursorPos(cX, cY); ConSetCursorSize(cStart, cEnd); if (cVisible) ConShowCursor(); else ConHideCursor(); return 0; } int GViewPeer::DrawScrollBar() { TDrawBuffer B; int NRows, NCols, I; int W, H; char fore = ConGetDrawChar(DCH_HFORE); char back = ConGetDrawChar(DCH_HBACK); ConQuerySize(&W, &H); if (ShowVScroll) { MoveCh(B, ConGetDrawChar(DCH_AUP), hcScrollBar_Arrows, 1); ConPutBox(W, 0, 1, 1, B); MoveCh(B, ConGetDrawChar(DCH_ADOWN), hcScrollBar_Arrows, 1); ConPutBox(W, H - 1, 1, 1, B); NRows = H - 2; if (sbVtotal <= NRows) { SbVBegin = 0; SbVEnd = NRows - 1; } else { SbVBegin = NRows * sbVstart / sbVtotal; SbVEnd = SbVBegin + NRows * sbVamount / sbVtotal; } for (I = 0; I < NRows; I++) { if (I >= SbVBegin && I <= SbVEnd) MoveCh(B, fore, hcScrollBar_Fore, 1); else MoveCh(B, back, hcScrollBar_Back, 1); ConPutBox(W, I + 1, 1, 1, B); } } if (ShowHScroll) { MoveCh(B, ConGetDrawChar(DCH_ALEFT), hcScrollBar_Arrows, 1); ConPutBox(0, H, 1, 1, B); MoveCh(B, ConGetDrawChar(DCH_ARIGHT), hcScrollBar_Arrows, 1); ConPutBox(W - 1, H, 1, 1, B); NCols = W - 2; if (sbHtotal <= NCols) { SbHBegin = 0; SbHEnd = NCols - 1; } else { SbHBegin = NCols * sbHstart / sbHtotal; SbHEnd = SbHBegin + NCols * sbHamount / sbHtotal; } // could be made faster for (I = 0; I < NCols; I++) { if (I >= SbHBegin && I <= SbHEnd) MoveCh(B, fore, hcScrollBar_Fore, 1); else MoveCh(B, back, hcScrollBar_Back, 1); ConPutBox(I + 1, H, 1, 1, B); } } if (ShowVScroll && ShowHScroll) { MoveCh(B, ' ', hcScrollBar_Arrows, 1); ConPutBox(W, H, 1, 1, B); } return 0; } /////////////////////////////////////////////////////////////////////////// GView::GView(GFrame *parent, int XSize, int YSize) { Parent = parent; Prev = Next = 0; Peer = new GViewPeer(this, XSize, YSize); if (Parent) Parent->AddView(this); } GView::~GView() { if (Parent) Parent->RemoveView(this); delete Peer; } int GView::ConClear() { int W, H; TDrawBuffer B; ConQuerySize(&W, &H); MoveChar(B, 0, W, ' ', 0x07, 1); ConSetBox(0, 0, W, H, B[0]); return 1; } int GView::ConPutBox(int X, int Y, int W, int H, PCell Cell) { return Peer->ConPutBox(X, Y, W, H, Cell); } int GView::ConGetBox(int X, int Y, int W, int H, PCell Cell) { return Peer->ConGetBox(X, Y, W, H, Cell); } int GView::ConPutLine(int X, int Y, int W, int H, PCell Cell) { return Peer->ConPutLine(X, Y, W, H, Cell); } int GView::ConSetBox(int X, int Y, int W, int H, TCell Cell) { return Peer->ConSetBox(X, Y, W, H, Cell); } int GView::ConScroll(int Way, int X, int Y, int W, int H, TAttr Fill, int Count) { return Peer->ConScroll(Way, X, Y, W, H, Fill, Count); } int GView::ConSetSize(int X, int Y) { if (Peer->ConSetSize(X, Y)) Resize(X, Y); else return 0; return 1; } int GView::ConQuerySize(int *X, int *Y) { return Peer->ConQuerySize(X, Y); } int GView::ConSetCursorPos(int X, int Y) { return Peer->ConSetCursorPos(X, Y); } int GView::ConQueryCursorPos(int *X, int *Y) { return Peer->ConQueryCursorPos(X, Y); } int GView::ConShowCursor() { return Peer->ConShowCursor(); } int GView::ConHideCursor() { return Peer->ConHideCursor(); } int GView::ConCursorVisible() { return Peer->ConCursorVisible(); } int GView::ConSetCursorSize(int Start, int End) { return Peer->ConSetCursorSize(Start, End); } int GView::CaptureMouse(int grab) { return Peer->CaptureMouse(grab); } int GView::CaptureFocus(int grab) { return Peer->CaptureFocus(grab); } int GView::QuerySbVPos() { return Peer->QuerySbVPos(); } int GView::SetSbVPos(int Start, int Amount, int Total) { return Peer->SetSbVPos(Start, Amount, Total); } int GView::SetSbHPos(int Start, int Amount, int Total) { return Peer->SetSbHPos(Start, Amount, Total); } int GView::ExpandHeight(int DeltaY) { return Peer->ExpandHeight(DeltaY); } void GView::Update() { } void GView::Repaint() { } void GView::HandleEvent(TEvent &/*Event*/) { } void GView::Resize(int /*width*/, int /*height*/) { Repaint(); } void GView::EndExec(int NewResult) { Result = NewResult; } int GView::Execute() { int SaveRc = Result; int NewResult; int didFocus = 0; if (FocusCapture == 0) { if (CaptureFocus(1) == 0) return -1; didFocus = 1; } else if (FocusCapture != this) return -1; Result = -2; while (Result == -2 && frames != 0) gui->ProcessEvent(); NewResult = Result; Result = SaveRc; if (didFocus) CaptureFocus(0); return NewResult; } int GView::IsActive() { return (Parent->Active == this); } void GView::Activate(int gotfocus) { if (gotfocus) { Peer->wState |= sfFocus; Peer->UpdateCursor(); } else { Peer->wState &= ~sfFocus; } Repaint(); } /////////////////////////////////////////////////////////////////////////// GFramePeer::GFramePeer(GFrame *aFrame, int Width, int Height) { Frame = aFrame; if (Width != -1 && Height != -1) ConSetSize(Width, Height); ConQuerySize(&fW, &fH); } GFramePeer::~GFramePeer() { } int GFramePeer::ConSetSize(int X, int Y) { return ::ConSetSize(X, Y); } int GFramePeer::ConQuerySize(int *X, int *Y) { ::ConQuerySize(&fW, &fH); if (X) *X = fW; if (Y) *Y = fH; return 1; } //int GFrame::ConQuerySize(int *X, int *Y) { // ::ConQuerySize(X, Y); // if (ShowVScroll) // --*X; //} int GFramePeer::ConSetTitle(char *Title, char *STitle) { ::ConSetTitle(Title, STitle); return 0; } int GFramePeer::ConGetTitle(char *Title, int MaxLen, char *STitle, int SMaxLen) { return ::ConGetTitle(Title, MaxLen, STitle, SMaxLen); } /////////////////////////////////////////////////////////////////////////// GFrame::GFrame(int XSize, int YSize) { Menu = 0; if (frames == 0) { frames = Prev = Next = this; } else { Next = frames->Next; Prev = frames; frames->Next->Prev = this; frames->Next = this; frames = this; } Top = Active = 0; Peer = new GFramePeer(this, XSize, YSize); } GFrame::~GFrame() { if (Peer) { delete Peer; Peer = 0; } if (Next == this) { frames = 0; // printf("No more frames\x7\x7\n"); } else { Next->Prev = Prev; Prev->Next = Next; frames = Next; } Next = Prev = 0; if (Menu) free(Menu); } int GFrame::ConSetTitle(char *Title, char *STitle) { return Peer->ConSetTitle(Title, STitle); } int GFrame::ConGetTitle(char *Title, int MaxLen, char *STitle, int SMaxLen) { return Peer->ConGetTitle(Title, MaxLen, STitle, SMaxLen); } int GFrame::ConSetSize(int X, int Y) { return Peer->ConSetSize(X, Y); } int GFrame::ConQuerySize(int *X, int *Y) { return Peer->ConQuerySize(X, Y); } int GFrame::ConSplitView(GView *view, GView *newview) { int dmy; newview->Parent = this; newview->Peer->wX = 0; ConQuerySize(&newview->Peer->wW, &dmy); if (ShowVScroll) newview->Peer->wW--; newview->Peer->wY = view->Peer->wY + view->Peer->wH / 2; newview->Peer->wH = view->Peer->wH - view->Peer->wH / 2; if (ShowHScroll) { newview->Peer->wY++; newview->Peer->wH--; } view->Peer->wH /= 2; view->ConSetSize(view->Peer->wW, view->Peer->wH); newview->ConSetSize(newview->Peer->wW, newview->Peer->wH); InsertView(view, newview); return 0; } int GFrame::ConCloseView(GView * /*view*/) { return 0; } int GFrame::ConResizeView(GView * /*view*/, int /*DeltaY*/) { return 0; } int GFrame::AddView(GView *view) { if (Active != 0) { return ConSplitView(Active, view); } else { int W, H; view->Parent = this; view->Prev = view->Next = 0; view->Peer->wX = 0; if (ShowMenuBar) view->Peer->wY = 1; else view->Peer->wY = 0; ConQuerySize(&W, &H); if (ShowMenuBar) H--; if (ShowVScroll) W--; if (ShowHScroll) H--; view->ConSetSize(W, H); InsertView(Top, view); return 0; } } void GFrame::Update() { GView *v = Active; UpdateMenu(); while (v) { v->Update(); if ((ShowVScroll || ShowHScroll) && (v->Peer->sbVupdate || v->Peer->sbHupdate)) { v->Peer->DrawScrollBar(); v->Peer->sbVupdate = 0; v->Peer->sbHupdate = 0; } v = v->Next; if (v == Active) break; } } void GFrame::UpdateMenu() { if (ShowMenuBar) DrawMenuBar(); } void GFrame::Repaint() { GView *v = Active; if (ShowMenuBar) DrawMenuBar(); while (v) { v->Repaint(); if (ShowVScroll || ShowHScroll) { v->Peer->DrawScrollBar(); v->Peer->sbVupdate = 0; v->Peer->sbHupdate = 0; } v = v->Next; if (v == Active) break; } } void GFrame::InsertView(GView *Prev, GView *view) { if (!view) return ; if (Prev) { view->Prev = Prev; view->Next = Prev->Next; Prev->Next = view; view->Next->Prev = view; } else { view->Prev = view->Next = view; Top = view; } if (Active == 0) { Active = view; Active->Activate(1); } } void GFrame::RemoveView(GView *view) { if (!view) return ; if (Active == view) Active->Activate(0); if (view->Next == view) { Top = Active = 0; delete this; } else { view->Next->Prev = view->Prev; view->Prev->Next = view->Next; if (Top == view) { Top = view->Next; Top->Peer->wY -= view->Peer->wH; Top->ConSetSize(Top->Peer->wW, Top->Peer->wH + view->Peer->wH + (ShowHScroll ? 1 : 0)); } else { view->Prev->ConSetSize(view->Prev->Peer->wW, view->Prev->Peer->wH + view->Peer->wH + (ShowHScroll ? 1 : 0)); } if (Active == view) { Active = view->Prev; Active->Activate(1); } } } void GFrame::SelectNext(int back) { GView *c = Active; if (c == 0 && Top == 0) return; if (FocusCapture != 0) return ; else if (c == 0) c = Active = Top; else if (back) { Active = Active->Prev; } else { Active = Active->Next; } if (c != Active) { if (c) c->Activate(0); if (Active) Active->Activate(1); } } int GFrame::SelectView(GView *view) { if (Top == 0) return 0; if (FocusCapture != 0) view = view; if (Active) Active->Activate(0); Active = view; if (Active) Active->Activate(1); return 1; } void GFrame::Resize(int width, int height) { GView *V; int count = 0; V = Top; while (V) { count++; if (V == Top) break; } if (height < 2 * count + 2 || width < 16) { ::ConSetSize(16, 2 * count + 1); return; } if (!Top) return; if (ShowVScroll) width--; if (ShowHScroll) height--; // fprintf(stderr, "Resize: %d %d\n", width, height); V = Top->Prev; while (V != Top) { int h, y; h = V->Peer->wH; y = V->Peer->wY; if (y >= height - 2) { y = height - 2; } if (y + h != height) { h = height - y; } V->Peer->wY = y; V->ConSetSize(width, h); height = y; V = V->Prev; } if (ShowMenuBar) height--; Top->ConSetSize(width, height); Repaint(); // fprintf(stderr, "Resize: %d %d Done\n", width, height); } int GFrame::ExecMainMenu(char Sub) { NextEvent.What = evCommand; NextEvent.Msg.Command = cmMainMenu; NextEvent.Msg.Param1 = Sub; return 0; } int GFrame::SetMenu(const char *Name) { if (Menu) free(Menu); Menu = strdup(Name); return 0; } void GFrame::Show() { } void GFrame::Activate() { frames = this; } int GUI::ConGrabEvents(TEventMask /*EventMask*/) { return 0; } void GUI::DispatchEvent(GFrame * /*frame*/, GView *view, TEvent &Event) { if (Event.What != evNone) { if (view) view->HandleEvent(Event); } } int GUI::ConGetEvent(TEventMask EventMask, TEvent *Event, int WaitTime, int Delete, GView **view) { if (view) *view = 0; return ::ConGetEvent(EventMask, Event, WaitTime, Delete); } int GUI::ConPutEvent(TEvent Event) { return ::ConPutEvent(Event); } int GUI::ConFlush(void) { return 0; } static inline int scrollBreak(TEvent &E) { #if defined(DOS) || defined(DOSP32) // workaround until mouse code in con_dosx.cpp is finished return (E.What != evMouseDown); #else return (E.What == evMouseUp); #endif } void HandleVScroll(GView *view, TEvent &E) { int y; //, x int wY, wH; TEvent E1; //x = E.Mouse.X; y = E.Mouse.Y; wY = view->Peer->wY; wH = view->Peer->wH; if (y == wY) { do { E1.What = evCommand; E1.Msg.View = view; E1.Msg.Command = cmVScrollUp; gui->DispatchEvent(frames, view, E1); frames->Update(); do { ConGetEvent(evMouse | evNotify, &E, -1, 1); if (E.What & evNotify) gui->DispatchEvent(frames, view, E); } while (E.What & evNotify); if (scrollBreak(E)) break; } while (1); } else if (y == wY + wH - 1) { do { E1.What = evCommand; E1.Msg.View = view; E1.Msg.Command = cmVScrollDown; gui->DispatchEvent(frames, view, E1); frames->Update(); do { ConGetEvent(evMouse | evNotify, &E, -1, 1); if (E.What & evNotify) gui->DispatchEvent(frames, view, E); } while (E.What & evNotify); if (scrollBreak(E)) break; } while (1); } else if (y < wY + view->Peer->SbVBegin + 1) { do { E1.What = evCommand; E1.Msg.View = view; E1.Msg.Command = cmVScrollPgUp; gui->DispatchEvent(frames, view, E1); frames->Update(); do { ConGetEvent(evMouse | evNotify, &E, -1, 1); if (E.What & evNotify) gui->DispatchEvent(frames, view, E); } while (E.What & evNotify); if (scrollBreak(E)) break; } while (1); } else if (y > wY + view->Peer->SbVEnd + 1) { do { E1.What = evCommand; E1.Msg.View = view; E1.Msg.Command = cmVScrollPgDn; gui->DispatchEvent(frames, view, E1); frames->Update(); do { ConGetEvent(evMouse | evNotify, &E, -1, 1); if (E.What & evNotify) gui->DispatchEvent(frames, view, E); } while (E.What & evNotify); if (scrollBreak(E)) break; } while (1); } else { int delta = y - 1 - view->Peer->SbVBegin - wY; do { E1.What = evCommand; E1.Msg.View = view; E1.Msg.Command = cmVScrollMove; E1.Msg.Param1 = (E.Mouse.Y - wY - 1 - delta + 1) * view->Peer->sbVtotal / (wH - 2); // printf("YPos = %d %d %d \n\x7", E.Mouse.Y, wY, delta); gui->DispatchEvent(frames, view, E1); frames->Update(); do { ConGetEvent(evMouse | evNotify, &E, -1, 1); if (E.What & evNotify) gui->DispatchEvent(frames, view, E); } while (E.What & evNotify); if (scrollBreak(E)) break; } while (1); } E.What = evNone; } void HandleHScroll(GView *view, TEvent &E) { int x; //, x int wX, wW; TEvent E1; //x = E.Mouse.X; x = E.Mouse.X; wX = view->Peer->wX; wW = view->Peer->wW; if (x == wX) { do { E1.What = evCommand; E1.Msg.View = view; E1.Msg.Command = cmHScrollLeft; gui->DispatchEvent(frames, view, E1); frames->Update(); do { ConGetEvent(evMouse | evNotify, &E, -1, 1); if (E.What & evNotify) gui->DispatchEvent(frames, view, E); } while (E.What & evNotify); if (scrollBreak(E)) break; } while (1); } else if (x == wX + wW - 1) { do { E1.What = evCommand; E1.Msg.View = view; E1.Msg.Command = cmHScrollRight; gui->DispatchEvent(frames, view, E1); frames->Update(); do { ConGetEvent(evMouse | evNotify, &E, -1, 1); if (E.What & evNotify) gui->DispatchEvent(frames, view, E); } while (E.What & evNotify); if (scrollBreak(E)) break; } while (1); } else if (x < wX + view->Peer->SbHBegin + 1) { do { E1.What = evCommand; E1.Msg.View = view; E1.Msg.Command = cmHScrollPgLt; gui->DispatchEvent(frames, view, E1); frames->Update(); do { ConGetEvent(evMouse | evNotify, &E, -1, 1); if (E.What & evNotify) gui->DispatchEvent(frames, view, E); } while (E.What & evNotify); if (scrollBreak(E)) break; } while (1); } else if (x > wX + view->Peer->SbHEnd + 1) { do { E1.What = evCommand; E1.Msg.View = view; E1.Msg.Command = cmHScrollPgRt; gui->DispatchEvent(frames, view, E1); frames->Update(); do { ConGetEvent(evMouse | evNotify, &E, -1, 1); if (E.What & evNotify) gui->DispatchEvent(frames, view, E); } while (E.What & evNotify); if (scrollBreak(E)) break; } while (1); } else { int delta = x - 1 - view->Peer->SbHBegin - wX; do { E1.What = evCommand; E1.Msg.View = view; E1.Msg.Command = cmHScrollMove; E1.Msg.Param1 = (E.Mouse.X - wX - 1 - delta + 1) * view->Peer->sbHtotal / (wW - 2); // printf("YPos = %d %d %d \n\x7", E.Mouse.Y, wY, delta); gui->DispatchEvent(frames, view, E1); frames->Update(); do { ConGetEvent(evMouse | evNotify, &E, -1, 1); if (E.What & evNotify) gui->DispatchEvent(frames, view, E); } while (E.What & evNotify); if (scrollBreak(E)) break; } while (1); } E.What = evNone; } void GUI::ProcessEvent() { TEvent E; E = NextEvent; if (E.What != evNone) { NextEvent.What = evNone; } if (E.What == evNone && ( ConGetEvent(evMouse | evCommand | evKeyboard, &E, 0, 1, 0) == -1 || E.What == evNone ) ) { frames->Update(); while(ConGetEvent(evMouse | evCommand | evKeyboard, &E, -1, 1, 0) == -1 || (E.What == evMouseMove && E.Mouse.Buttons == 0)); } if (E.What != evNone) { GView *view = frames->Active; if (E.What & evMouse) { if (E.What == evMouseDown && E.Mouse.Y == 0 && ShowMenuBar && MouseCapture == 0 && FocusCapture == 0) { frames->Update(); // sync before menu if (ExecMainMenu(E, 0) == -1) { if (E.What == evCommand && E.Msg.Command == cmResize) { int X, Y; ConQuerySize(&X, &Y); frames->Resize(X, Y); } E.What = evNone; } // fprintf(stderr, "Command got = %d\n", E.Msg.Command); } if (E.What == evMouseDown && MouseCapture == 0 && FocusCapture == 0) { GView *V = frames->Active; while (V) { if (E.Mouse.Y >= V->Peer->wY && E.Mouse.Y < V->Peer->wY + V->Peer->wH + (ShowHScroll ? 1 : 0)) { frames->SelectView(V); view = V; break; } V = V->Next; if (V == frames->Active) break; } } if (ShowVScroll && ShowHScroll && E.What == evMouseDown && MouseCapture == 0 && FocusCapture == 0 && E.Mouse.Y == view->Peer->wY + view->Peer->wH && E.Mouse.X == view->Peer->wX + view->Peer->wW) { } else { if (ShowVScroll && E.What == evMouseDown && MouseCapture == 0 && FocusCapture == 0 && E.Mouse.X == view->Peer->wX + view->Peer->wW) { HandleVScroll(view, E); return ; } if (ShowHScroll && E.What == evMouseDown && MouseCapture == 0 && FocusCapture == 0 && E.Mouse.Y == view->Peer->wY + view->Peer->wH) { HandleHScroll(view, E); return ; } } if (E.What & evMouse) { E.Mouse.Y -= view->Peer->wY; E.Mouse.X -= view->Peer->wX; } } if (E.What == evCommand) { switch (E.Msg.Command) { case cmResize: { int X, Y; ConQuerySize(&X, &Y); frames->Resize(X, Y); } break; case cmMainMenu: { char Sub = (char)E.Msg.Param1; frames->Update(); // sync before menu if (::ExecMainMenu(E, Sub) != 1) {; if (E.What == evCommand && E.Msg.Command == cmResize) { int X, Y; ConQuerySize(&X, &Y); frames->Resize(X, Y); } E.What = evNone; } } break; case cmPopupMenu: { int id = E.Msg.Param1; int Cols, Rows; if (id == -1) return; frames->ConQuerySize(&Cols, &Rows); int x = Cols / 2, y = Rows / 2; ::ConQueryMousePos(&x, &y); frames->Update(); // sync before menu if (::ExecVertMenu(x, y, id, E, 0) != 1) { if (E.What == evCommand && E.Msg.Command == cmResize) { int X, Y; ConQuerySize(&X, &Y); frames->Resize(X, Y); } E.What = evNone; } } break; } } if (E.What != evNone) DispatchEvent(frames, view, E); } } int GUI::Run() { if (Start(fArgc, fArgv) == 0) { doLoop = 1; while (doLoop) ProcessEvent(); Stop(); return 0; } return 1; } int GUI::multiFrame() { return 0; } void DieError(int rc, const char *msg, ...) { va_list ap; va_start(ap, msg); vfprintf(stderr, msg, ap); va_end(ap); fprintf(stderr, "\n"); exit(rc); }