/* * colorsel.cc * * Turbo Vision - Version 2.0 * * Copyright (c) 1994 by Borland International * All Rights Reserved. * * Modified by Sergio Sigala */ #define Uses_TKeys #define Uses_TColorSelector #define Uses_TMonoSelector #define Uses_TColorDisplay #define Uses_TColorItem #define Uses_TColorItemList #define Uses_TColorGroup #define Uses_TColorGroupList #define Uses_TColorDialog #define Uses_TEvent #define Uses_TDrawBuffer #define Uses_TGroup #define Uses_TSItem #define Uses_TScrollBar #define Uses_TLabel #define Uses_TButton #define Uses_TRect #define Uses_opstream #define Uses_ipstream #include #include static TColorIndex* colorIndexes = 0; TColorItem::TColorItem( const char *nm, uchar idx, TColorItem *nxt ) { index = idx; next = nxt; name = newStr( nm ); } TColorItem::~TColorItem() { delete (char *)name; } TColorGroup::TColorGroup( const char *nm, TColorItem *itm, TColorGroup *nxt ) { items = itm; next = nxt; name = newStr( nm ); } TColorGroup::~TColorGroup() { delete (char *)name; } TColorItem& operator + ( TColorItem& i1, TColorItem& i2 ) { TColorItem *cur = &i1; while( cur->next != 0 ) cur = cur->next; cur->next = &i2; return i1; } TColorGroup& operator + ( TColorGroup& g, TColorItem& i ) { TColorGroup *grp = &g; while( grp->next != 0 ) grp = grp->next; if( grp->items == 0 ) grp->items = &i; else { TColorItem *cur = grp->items; while( cur->next != 0 ) cur = cur->next; cur->next = &i; } return g; } TColorGroup& operator + ( TColorGroup& g1, TColorGroup& g2 ) { TColorGroup *cur = &g1; while( cur->next != 0 ) cur = cur->next; cur->next = &g2; return g1; } TColorSelector::TColorSelector( const TRect& bounds, ColorSel aSelType ) : TView( bounds ) { options |= ofSelectable | ofFirstClick | ofFramed; eventMask |= evBroadcast; selType = aSelType; color = 0; } void TColorSelector::draw() { TDrawBuffer b; b.moveChar( 0, ' ', 0x70, size.x ); for(int i = 0; i <= size.y; i++ ) { if( i < 4 ) { for( int j = 0; j < 4; j++ ) { int c = i*4+j; b.moveChar( j*3, icon, c, 3 ); if( c == color ) { b.putChar( j*3+1, 8 ); if( c == 0 ) b.putAttribute( j*3+1, 0x70 ); } } } writeLine( 0, i, size.x, 1, b ); } } void TColorSelector::colorChanged() { int msg; if( selType == csForeground ) msg = cmColorForegroundChanged; else msg = cmColorBackgroundChanged; message( owner, evBroadcast, msg, (void *)color ); } void TColorSelector::handleEvent( TEvent& event ) { const int width = 4; TView::handleEvent( event ); uchar oldColor = color; int maxCol = (selType == csBackground) ? 7 : 15; switch( event.what ) { case evMouseDown: do { if( mouseInView( event.mouse.where ) ) { TPoint mouse = makeLocal( event.mouse.where ); color = mouse.y*4 + mouse.x/3; } else color = oldColor; colorChanged(); drawView(); } while( mouseEvent( event, evMouseMove ) ); break; case evKeyDown: switch( ctrlToArrow( event.keyDown.keyCode ) ) { case kbLeft: if( color > 0 ) color--; else color = maxCol; break; case kbRight: if( color < maxCol ) color++; else color = 0; break; case kbUp: if( color > width-1 ) color -= width; else if( color == 0 ) color = maxCol; else color += maxCol - width; break; case kbDown: if( color < maxCol - (width-1) ) color += width; else if( color == maxCol ) color = 0; else color -= maxCol - width; break; default: return; } break; case evBroadcast: if( event.message.command == cmColorSet ) { /* * SS: some non-portable code changed. */ if( selType == csBackground ) color = (int)event.message.infoPtr >> 4; else color = (int)event.message.infoPtr & 0x0F; drawView(); return ; } else return; default: return ; } drawView(); colorChanged(); clearEvent( event ); } #if !defined(NO_STREAMABLE) void TColorSelector::write( opstream& os ) { TView::write( os ); os << color << (int)selType; } void *TColorSelector::read( ipstream& is ) { int temp; TView::read( is ); is >> color >> temp; selType = ColorSel(temp); return this; } TStreamable *TColorSelector::build() { return new TColorSelector( streamableInit ); } TColorSelector::TColorSelector( StreamableInit ) : TView( streamableInit ) { } #endif const uchar monoColors[] = { 0x07, 0x0F, 0x01, 0x70, 0x09 }; TMonoSelector::TMonoSelector( const TRect& bounds ) : TCluster( bounds, new TSItem( normal, new TSItem( highlight, new TSItem( underline, new TSItem( inverse, 0 ))))) { eventMask |= evBroadcast; } void TMonoSelector::draw() { drawBox( button, 0x07 ); } void TMonoSelector::handleEvent( TEvent& event ) { TCluster::handleEvent( event ); if( event.what == evBroadcast && event.message.command == cmColorSet ) { /* * SS: some non-portable code changed. */ value = (int)event.message.infoPtr; drawView(); } } Boolean TMonoSelector::mark( int item ) { return Boolean(monoColors[item] == value); } void TMonoSelector::newColor() { message( owner, evBroadcast, cmColorForegroundChanged, (void *)(value & 0x0F) ); message( owner, evBroadcast, cmColorBackgroundChanged, (void *)((value >> 4) & 0x0F)); } void TMonoSelector::press( int item ) { value = monoColors[item]; newColor(); } void TMonoSelector::movedTo( int item ) { value = monoColors[item]; newColor(); } #if !defined(NO_STREAMABLE) TStreamable *TMonoSelector::build() { return new TMonoSelector( streamableInit ); } TMonoSelector::TMonoSelector( StreamableInit ) : TCluster( streamableInit ) { } #endif TColorDisplay::TColorDisplay( const TRect& bounds, const char *aText ) : TView( bounds ), color( 0 ), text( newStr( aText ) ) { eventMask |= evBroadcast; } TColorDisplay::~TColorDisplay() { delete (char *)text; } void TColorDisplay::draw() { uchar c = *color; if( c == 0 ) c = errorAttr; const int len = strlen( text ); TDrawBuffer b; for( int i = 0; i <= size.x/len; i++ ) b.moveStr( i*len, text, c ); writeLine( 0, 0, size.x, size.y, b ); } void TColorDisplay::handleEvent( TEvent& event ) { TView::handleEvent( event ); if( event.what == evBroadcast ) switch( event.message.command ) { case cmColorBackgroundChanged: /* * SS: some non-portable code changed. */ *color = (*color & 0x0F) | (((int)event.message.infoPtr << 4) & 0xF0); drawView(); break; case cmColorForegroundChanged: *color = (*color & 0xF0) | ((int)event.message.infoPtr & 0x0F); drawView(); } } void TColorDisplay::setColor( uchar *aColor ) { color = aColor; message( owner, evBroadcast, cmColorSet, (void *)(*color) ); drawView(); } #if !defined(NO_STREAMABLE) void TColorDisplay::write( opstream& os ) { TView::write( os ); os.writeString( text ); } void *TColorDisplay::read( ipstream& is ) { TView::read( is ); text = is.readString(); color = 0; return this; } TStreamable *TColorDisplay::build() { return new TColorDisplay( streamableInit ); } TColorDisplay::TColorDisplay( StreamableInit ) : TView( streamableInit ) { } #endif TColorGroupList::TColorGroupList( const TRect& bounds, TScrollBar *aScrollBar, TColorGroup *aGroups ) : TListViewer( bounds, 1, 0, aScrollBar ), groups( aGroups ) { int i = 0; while( aGroups != 0 ) { aGroups = aGroups->next; i++; } setRange(i); } static void freeItems( TColorItem *curItem ) { while( curItem != 0 ) { TColorItem *p = curItem; curItem = curItem->next; delete p; } } static void freeGroups( TColorGroup *curGroup ) { while( curGroup != 0 ) { TColorGroup *p = curGroup; freeItems( curGroup->items ); curGroup = curGroup->next; delete p; } } TColorGroupList::~TColorGroupList() { freeGroups( groups ); } void TColorGroupList::focusItem( short item ) { TListViewer::focusItem( item ); TColorGroup *curGroup = groups; while( item-- > 0 ) curGroup = curGroup->next; message( owner, evBroadcast, cmNewColorItem, curGroup); } void TColorGroupList::getText( char *dest, short item, short maxChars ) { TColorGroup *curGroup = groups; while( item-- > 0 ) curGroup = curGroup->next; strncpy( dest, curGroup->name, maxChars ); dest[maxChars] = '\0'; } #if !defined(NO_STREAMABLE) void TColorGroupList::writeItems( opstream& os, TColorItem *items ) { int count = 0; TColorItem *cur; for( cur = items; cur != 0; cur = cur->next ) count++; os << count; for( cur = items; cur != 0; cur = cur->next ) { os.writeString( cur->name ); os << cur->index; } } void TColorGroupList::writeGroups( opstream& os, TColorGroup *groups ) { int count = 0; TColorGroup *cur; for( cur = groups; cur != 0; cur = cur->next ) count++; os << count; for( cur = groups; cur != 0; cur = cur->next ) { os.writeString( cur->name ); writeItems( os, cur->items ); } } #endif void TColorGroupList::handleEvent(TEvent& ev) { TListViewer::handleEvent(ev); if ((ev.what == evBroadcast) && (ev.message.command == cmSaveColorIndex)) /* * SS: some non-portable code changed. */ setGroupIndex(focused, (int)ev.message.infoPtr); } void TColorGroupList::setGroupIndex(uchar groupNum, uchar itemNum) { TColorGroup* g = getGroup(groupNum); if (g) g->index = itemNum; } uchar TColorGroupList::getGroupIndex(uchar groupNum) { TColorGroup* g = getGroup(groupNum); if (g) return g->index; else /* SS: this makes g++ happy */ return (uchar) NULL; } TColorGroup* TColorGroupList::getGroup(uchar groupNum) { TColorGroup* g = groups; while (groupNum--) g = g->next; return g; } uchar TColorGroupList::getNumGroups() { uchar n; TColorGroup* g = groups; for (n=0; g; n++) g = g->next; return n; } #if !defined(NO_STREAMABLE) void TColorGroupList::write( opstream& os ) { TListViewer::write( os ); writeGroups( os, groups ); } TColorItem *TColorGroupList::readItems( ipstream& is ) { int count; is >> count; TColorItem *items = 0; TColorItem **cur = &items; while( count-- > 0 ) { char *nm = is.readString(); uchar index; is >> index; *cur = new TColorItem( nm, index ); delete nm; cur = &((*cur)->next); } *cur = 0; return items; } TColorGroup *TColorGroupList::readGroups( ipstream& is ) { int count; is >> count; TColorGroup *groups = 0; TColorGroup **cur = &groups; while( count-- > 0 ) { char *nm = is.readString(); TColorItem *grp = readItems( is ); *cur = new TColorGroup( nm, grp ); cur = &((*cur)->next); delete nm; } *cur = 0; return groups; } void *TColorGroupList::read( ipstream& is ) { TListViewer::read( is ); groups = readGroups( is ); return this; } TStreamable *TColorGroupList::build() { return new TColorGroupList( streamableInit ); } TColorGroupList::TColorGroupList( StreamableInit ) : TListViewer( streamableInit ) { } #endif TColorItemList::TColorItemList( const TRect& bounds, TScrollBar *aScrollBar, TColorItem *aItems ) : TListViewer( bounds, 1, 0, aScrollBar ), items( aItems ) { eventMask |= evBroadcast; int i = 0; while( aItems != 0 ) { aItems = aItems->next; i++; } setRange( i ); } void TColorItemList::focusItem( short item ) { TListViewer::focusItem( item ); message(owner,evBroadcast, cmSaveColorIndex, (void*)item); TColorItem *curItem = items; while( item-- > 0 ) curItem = curItem->next; message( owner, evBroadcast, cmNewColorIndex, (void *)(curItem->index)); } void TColorItemList::getText( char *dest, short item, short maxChars ) { TColorItem *curItem = items; while( item-- > 0 ) curItem = curItem->next; strncpy( dest, curItem->name, maxChars ); dest[maxChars] = '\0'; } void TColorItemList::handleEvent( TEvent& event ) { TListViewer::handleEvent( event ); if( event.what == evBroadcast ) { TColorGroup* g = (TColorGroup*) event.message.infoPtr; TColorItem *curItem; int i = 0; switch(event.message.command) { case cmNewColorItem: curItem = items = g->items; while( curItem != 0 ) { curItem = curItem->next; i++; } setRange( i ); focusItem( g->index); drawView(); break; default: break; } } } #if !defined(NO_STREAMABLE) TStreamable *TColorItemList::build() { return new TColorItemList( streamableInit ); } TColorItemList::TColorItemList( StreamableInit ) : TListViewer( streamableInit ) { } #endif TColorDialog::TColorDialog( TPalette *aPalette, TColorGroup *aGroups ): #if 1 //__UNPATCHED TDialog( TRect( 0, 0, 79, 18 ), colors ), #else TDialog( TRect( 0, 0, 61, 18 ), colors ), #endif TWindowInit( &TColorDialog::initFrame ) { options |= ofCentered; if( aPalette != 0 ) { pal = new TPalette( "", 0 ); *pal = *aPalette; } else pal = 0; #if 1 //__UNPATCHED TScrollBar *sb = new TScrollBar( TRect( 27, 3, 28, 14 ) ); insert( sb ); groups = new TColorGroupList( TRect( 3, 3, 27, 14 ), sb, aGroups); insert( groups ); insert( new TLabel( TRect( 3, 2, 10, 3 ), groupText, groups ) ); sb = new TScrollBar( TRect( 59, 3, 60, 14 ) ); insert( sb ); TView *p = new TColorItemList( TRect( 30, 3, 59, 14 ), sb, aGroups->items ); insert( p ); insert( new TLabel( TRect( 30, 2, 36, 3 ), itemText, p ) ); forSel = new TColorSelector( TRect( 63, 3, 75, 7 ), TColorSelector::csForeground ); insert( forSel ); forLabel = new TLabel( TRect( 63, 2, 75, 3 ), forText, forSel ); insert( forLabel ); bakSel = new TColorSelector( TRect( 63, 9, 75, 11 ), TColorSelector::csBackground ); insert( bakSel ); bakLabel = new TLabel( TRect( 63, 8, 75, 9 ), bakText, bakSel ); insert( bakLabel ); display = new TColorDisplay( TRect( 62, 12, 76, 14 ), textText ); insert( display ); monoSel = new TMonoSelector( TRect( 62, 3, 77, 7 ) ); monoSel->hide(); insert( monoSel ); monoLabel = new TLabel( TRect( 62, 2, 69, 3 ), colorText, monoSel ); monoLabel->hide(); insert( monoLabel ); insert( new TButton( TRect( 51, 15, 61, 17 ), okText, cmOK, bfDefault ) ); insert( new TButton( TRect( 63, 15, 73, 17 ), cancelText, cmCancel, bfNormal ) ); selectNext( False ); #else TScrollBar *sb = new TScrollBar( TRect( 18, 3, 19, 14 ) ); insert( sb ); groups = new TColorGroupList( TRect( 3, 3, 18, 14 ), sb, aGroups); insert( groups ); insert( new TLabel( TRect( 2, 2, 8, 3 ), groupText, groups ) ); sb = new TScrollBar( TRect( 41, 3, 42, 14 ) ); insert( sb ); TView *p = new TColorItemList( TRect( 21, 3, 41, 14 ), sb, aGroups->items ); insert( p ); insert( new TLabel( TRect( 20, 2, 25, 3 ), itemText, p ) ); forSel = new TColorSelector( TRect( 45, 3, 57, 7 ), TColorSelector::csForeground ); insert( forSel ); forLabel = new TLabel( TRect( 45, 2, 57, 3 ), forText, forSel ); insert( forLabel ); bakSel = new TColorSelector( TRect( 45, 9, 57, 11 ), TColorSelector::csBackground ); insert( bakSel ); bakLabel = new TLabel( TRect( 45, 8, 57, 9 ), bakText, bakSel ); insert( bakLabel ); display = new TColorDisplay( TRect( 44, 12, 58, 14 ), textText ); insert( display ); monoSel = new TMonoSelector( TRect( 44, 3, 59, 7 ) ); monoSel->hide(); insert( monoSel ); monoLabel = new TLabel( TRect( 43, 2, 49, 3 ), colorText, monoSel ); monoLabel->hide(); insert( monoLabel ); insert( new TButton( TRect( 36, 15, 46, 17 ), okText, cmOK, bfDefault ) ); insert( new TButton( TRect( 48, 15, 58, 17 ), cancelText, cmCancel, bfNormal ) ); selectNext( False ); #endif if( pal != 0 ) setData( pal ); } TColorDialog::~TColorDialog() { delete pal; } void TColorDialog::handleEvent( TEvent& event ) { if( event.what==evBroadcast && event.message.command==cmNewColorItem ) groupIndex = groups->focused; TDialog::handleEvent( event ); if( event.what==evBroadcast && event.message.command==cmNewColorIndex ) /* * SS: some non-portable code changed. */ display->setColor( (uchar *)&pal->data[(int)event.message.infoPtr] ); } ushort TColorDialog::dataSize() { return *pal->data + 1; } void TColorDialog::getData( void *rec ) { getIndexes(colorIndexes); *(TPalette *) rec = *pal; } void TColorDialog::setData( void *rec) { if( !pal ) pal = new TPalette("", 0); *pal = *(TPalette *) rec; setIndexes(colorIndexes); display->setColor((uchar *)&pal->data[groups->getGroupIndex(groupIndex)]); groups->focusItem( groupIndex); if( showMarkers ) { forLabel->hide(); forSel->hide(); bakLabel->hide(); bakSel->hide(); monoLabel->show(); monoSel->show(); } groups->select(); } void TColorDialog::setIndexes(TColorIndex*& colIdx) { uchar numGroups, index; numGroups = groups->getNumGroups(); if (colIdx && (colIdx->colorSize != numGroups)) { delete colIdx; #ifndef __UNPATCHED colIdx = NULL; // BUG FIX #else colors = NULL; #endif } if (!colIdx) { colIdx = (TColorIndex*) new uchar[numGroups+2]; colIdx->groupIndex = 0; memset(colIdx->colorIndex, 0, numGroups); colIdx->colorSize = numGroups; } for (index = 0; index < numGroups; index++) groups->setGroupIndex(index, colIdx->colorIndex[index]); groupIndex = colIdx->groupIndex; } void TColorDialog::getIndexes(TColorIndex*& colIdx) { uchar n = groups->getNumGroups(); if (!colIdx) { colIdx = (TColorIndex*) new uchar[n+2]; memset(colIdx->colorIndex, 0, n); colIdx->colorSize = n; } colIdx->groupIndex = groupIndex; for (uchar index=0; index < n; index++) colIdx->colorIndex[index] = groups->getGroupIndex(index); } #if !defined(NO_STREAMABLE) void TColorDialog::write( opstream& os ) { TDialog::write( os ); os << display << groups << forLabel << forSel << bakLabel << bakSel << monoLabel << monoSel; } void *TColorDialog::read( ipstream& is ) { TDialog::read( is ); is >> display >> groups >> forLabel >> forSel >> bakLabel >> bakSel >> monoLabel >> monoSel; pal = 0; return this; } TStreamable *TColorDialog::build() { return new TColorDialog( streamableInit ); } TColorDialog::TColorDialog( StreamableInit ) : TDialog( streamableInit ), TWindowInit( 0 /*streamableInit*/ ) { } #endif