Ticket #1701: colorControl8.diff

File colorControl8.diff, 22.3 KB (added by aldeck, 12 months ago)
  • src/kits/interface/ColorControl.cpp

     
    55 * Authors: 
    66 *              Marc Flerackers (mflerackers@androme.be) 
    77 *              Axel Dörfler, axeld@pinc-software.de 
     8 *              Alexandre Deckner, alex@zappotek.com 
    89 */ 
    910 
    1011/**     BColorControl displays a palette of selectable colors. */ 
     
    2324 
    2425static const uint32 kMsgColorEntered = 'ccol'; 
    2526static const uint32 kMinCellSize = 6; 
     27static const float kSelectorPenSize = 2.0f; 
     28static const float kSelectorSize = 4.0f; 
     29static const float kSelectorHSpacing = 2.0f; 
     30static const float kTextFieldsHSpacing = 6.0f; 
    2631 
    27  
    2832BColorControl::BColorControl(BPoint leftTop, color_control_layout layout, 
    2933        float cellSize, const char *name, BMessage *message, 
    3034        bool bufferedDrawing) 
     
    6165{ 
    6266        fColumns = layout; 
    6367        fRows = 256 / fColumns; 
    64         fCellSize = max_c(kMinCellSize, size); 
     68        fCellSize = ceil(max_c(kMinCellSize, size)); 
     69        //TODO: check the colorspace dynamically? 
     70        fPaletteMode = BScreen(Window()).ColorSpace() == B_CMAP8; 
     71        fSelectedPaletteColorIndex = -1; 
     72        fPreviousSelectedPaletteColorIndex = -1; 
    6573        fFocusedComponent = 0; 
     74                 
     75        if (fPaletteMode){ 
     76                fPaletteFrame.Set(2.0f, 2.0f, 
     77                        float(fColumns) * fCellSize + 2.0, 
     78                        float(fRows) * fCellSize + 2.0); 
     79        } else {                 
     80                fPaletteFrame.Set(2.0f, 2.0f, 
     81                        float(fColumns) * fCellSize + 2.0, 
     82                        float(fRows) * fCellSize + 2.0 - 1.0); 
     83                        //1 pixel adjust so that the inner space  
     84                        //has exactly rows*cellsize pixels in height 
     85        } 
    6686 
    6787        if (archive) { 
    6888                int32 value = 0; 
     
    129149        } 
    130150 
    131151        if (useOffscreen) { 
    132                 BRect bounds(Bounds()); 
    133                 bounds.right = floorf(fBlueText->Frame().left) - 1; 
    134          
    135                 fBitmap = new BBitmap(bounds, /*BScreen(Window()).ColorSpace()*/B_RGB32, true, false); 
     152                BRect bounds = fPaletteFrame; 
     153                bounds.InsetBy(-2.0f, -2.0f);  
     154                 
     155                fBitmap = new BBitmap(bounds, BScreen(Window()).ColorSpace(), true, false); 
    136156                fOffscreenView = new BView(bounds, "off_view", 0, 0); 
    137157 
    138158                fBitmap->Lock(); 
     
    148168void 
    149169BColorControl::_LayoutView() 
    150170{ 
    151         BRect rect(0.0f, 0.0f, ceil(fColumns * fCellSize), ceil(fRows * fCellSize + 2)); 
    152  
     171        BRect rect = fPaletteFrame.InsetByCopy(-2.0,-2.0);      //bevel 
     172         
    153173        if (rect.Height() < fBlueText->Frame().bottom) { 
    154174                // adjust the height to fit 
    155175                rect.bottom = fBlueText->Frame().bottom; 
    156176        } 
    157  
    158         ResizeTo(rect.Width() + fRedText->Bounds().Width(), rect.Height()); 
    159  
     177         
    160178        float offset = floor(rect.bottom / 4); 
    161179        float y = offset; 
    162180        if (offset < fRedText->Bounds().Height() + 2) { 
    163181                offset = fRedText->Bounds().Height() + 2; 
    164182                y = 0; 
    165         } 
     183        }        
    166184 
    167         fRedText->MoveTo(rect.right + 1, y); 
     185        fRedText->MoveTo(rect.right + kTextFieldsHSpacing, y); 
    168186 
    169187        y += offset; 
    170         fGreenText->MoveTo(rect.right + 1, y); 
     188        fGreenText->MoveTo(rect.right + kTextFieldsHSpacing, y); 
    171189 
    172190        y += offset; 
    173         fBlueText->MoveTo(rect.right + 1, y); 
     191        fBlueText->MoveTo(rect.right + kTextFieldsHSpacing, y); 
     192         
     193        ResizeTo(rect.Width() + kTextFieldsHSpacing + fRedText->Bounds().Width(), rect.Height()); 
     194 
    174195} 
    175196 
    176197 
     
    220241        c2.red = (value & 0xFF000000) >> 24; 
    221242        c2.green = (value & 0x00FF0000) >> 16; 
    222243        c2.blue = (value & 0x0000FF00) >> 8; 
     244        c2.alpha = 255; 
    223245        char string[4]; 
    224246 
    225         // values for calculating the selector rectangles for invalidation 
    226         // analogous to selector drawing in _DrawColorArea 
    227         float rampXGradient = (ceil(fColumns * fCellSize) - 4 - 7)  / 255; 
    228         float rampSize = (Bounds().bottom - 2) / 4.0; 
    229         float x, y; 
    230  
    231         if (c1.red != c2.red) { 
     247        if (fPaletteMode) { 
     248                 
     249                //workaround when two indexes have the same color 
     250                rgb_color c = BScreen(Window()).ColorForIndex(fSelectedPaletteColorIndex); 
     251                c.alpha = 255; 
     252                if (fSelectedPaletteColorIndex == -1 || c != c2) { 
     253                                //here SetValue hasn't been called by mouse tracking 
     254                        fSelectedPaletteColorIndex = BScreen(Window()).IndexForColor(c2); 
     255                }                                
     256                                 
     257                c2 = BScreen(Window()).ColorForIndex(fSelectedPaletteColorIndex);        
     258                 
    232259                sprintf(string, "%d", c2.red); 
    233260                fRedText->SetText(string); 
    234                  
    235                 y = rampSize * 1.5; 
    236                 x = 2 + c1.red * rampXGradient; 
    237                 Invalidate(BRect(x - 2, y - 2, x + 6, y + 6)); 
    238                 x = 2 + c2.red * rampXGradient; 
    239                 Invalidate(BRect(x - 2, y - 2, x + 6, y + 6)); 
    240         } 
    241  
    242         if (c1.green != c2.green) { 
    243261                sprintf(string, "%d", c2.green); 
    244262                fGreenText->SetText(string); 
    245  
    246                 y = rampSize * 2.5;              
    247                 x = 2 + c1.green * rampXGradient; 
    248                 Invalidate(BRect(x - 2, y - 2, x + 6, y + 6)); 
    249                 x = 2 + c2.green * rampXGradient; 
    250                 Invalidate(BRect(x - 2, y - 2, x + 6, y + 6)); 
    251         } 
    252         if (c1.blue != c2.blue) { 
    253263                sprintf(string, "%d", c2.blue); 
    254264                fBlueText->SetText(string); 
    255265                 
    256                 y = rampSize * 3.5; 
    257                 x = 2 + c1.blue * rampXGradient; 
    258                 Invalidate(BRect(x - 2, y - 2, x + 6, y + 6)); 
    259                 x = 2 + c2.blue * rampXGradient; 
    260                 Invalidate(BRect(x - 2, y - 2, x + 6, y + 6)); 
     266                Invalidate(_PaletteSelectorFrame(fPreviousSelectedPaletteColorIndex)); 
     267                Invalidate(_PaletteSelectorFrame(fSelectedPaletteColorIndex));           
     268                 
     269                fPreviousSelectedPaletteColorIndex = fSelectedPaletteColorIndex;                                                                 
     270         
     271        } else { 
     272                         
     273                float invalidateRadius = kSelectorSize/2 + kSelectorPenSize; 
     274                BPoint p; 
     275                 
     276                if (c1.red != c2.red) { 
     277                        sprintf(string, "%d", c2.red); 
     278                        fRedText->SetText(string); 
     279                         
     280                        p = _SelectorPosition(_RampFrame(1), c1.red); 
     281                        Invalidate(BRect(p.x - invalidateRadius, p.y - invalidateRadius, 
     282                                 p.x + invalidateRadius, p.y + invalidateRadius));       
     283                                  
     284                        p = _SelectorPosition(_RampFrame(1), c2.red); 
     285                        Invalidate(BRect(p.x - invalidateRadius, p.y - invalidateRadius, 
     286                                 p.x + invalidateRadius, p.y + invalidateRadius));       
     287                } 
     288         
     289                if (c1.green != c2.green) { 
     290                        sprintf(string, "%d", c2.green); 
     291                        fGreenText->SetText(string); 
     292         
     293                        p = _SelectorPosition(_RampFrame(2), c1.green); 
     294                        Invalidate(BRect(p.x - invalidateRadius, p.y - invalidateRadius, 
     295                                 p.x + invalidateRadius, p.y + invalidateRadius)); 
     296                                         
     297                        p = _SelectorPosition(_RampFrame(2), c2.green); 
     298                        Invalidate(BRect(p.x - invalidateRadius, p.y - invalidateRadius, 
     299                                 p.x + invalidateRadius, p.y + invalidateRadius));               
     300                } 
     301                if (c1.blue != c2.blue) { 
     302                        sprintf(string, "%d", c2.blue); 
     303                        fBlueText->SetText(string); 
     304                         
     305                        p = _SelectorPosition(_RampFrame(3), c1.blue); 
     306                        Invalidate(BRect(p.x - invalidateRadius, p.y - invalidateRadius, 
     307                                 p.x + invalidateRadius, p.y + invalidateRadius)); 
     308                                         
     309                        p = _SelectorPosition(_RampFrame(3), c2.blue); 
     310                        Invalidate(BRect(p.x - invalidateRadius, p.y - invalidateRadius, 
     311                                 p.x + invalidateRadius, p.y + invalidateRadius));                               
     312                }  
    261313        } 
    262314 
    263315        BControl::SetValueNoUpdate(value); 
     
    308360        fRedText->SetTarget(this); 
    309361        fGreenText->SetTarget(this); 
    310362        fBlueText->SetTarget(this); 
     363         
     364        if (fBitmap) 
     365                _InitOffscreen();        
    311366} 
    312367 
    313368 
     
    318373                case kMsgColorEntered: 
    319374                { 
    320375                        rgb_color color; 
    321                         color.red = strtol(fRedText->Text(), NULL, 10); 
    322                         color.green = strtol(fGreenText->Text(), NULL, 10); 
    323                         color.blue = strtol(fBlueText->Text(), NULL, 10); 
     376                        color.red = /*min_c(*/strtol(fRedText->Text(), NULL, 10), 255/*)*/; 
     377                        color.green = /*min_c(*/strtol(fGreenText->Text(), NULL, 10), 255/*)*/; 
     378                        color.blue = /*min_c(*/strtol(fBlueText->Text(), NULL, 10), 255/*)*/; 
    324379                        color.alpha = 255; 
    325  
     380                                 
     381                        //TODO: text is not updated if the clamping 
     382                        //              gives the same value next time 
     383                                         
    326384                        SetValue(color); 
    327385                        Invoke(); 
    328386                        break; 
     
    341399                        return; 
    342400 
    343401                if (fOffscreenView->Bounds().Intersects(updateRect)) { 
    344                         _UpdateOffscreen(updateRect); 
    345402                        BRegion region(updateRect); 
    346403                        ConstrainClippingRegion(&region); 
    347404                        DrawBitmap(fBitmap, B_ORIGIN); 
     
    349406                } 
    350407 
    351408                fBitmap->Unlock(); 
     409                _DrawSelectors(this); 
     410                 
    352411        } else 
    353412                _DrawColorArea(this, updateRect); 
     413                _DrawSelectors(this); 
    354414} 
    355415 
    356416 
     
    359419{ 
    360420        BRegion region(update); 
    361421        target->ConstrainClippingRegion(&region); 
    362  
    363         BRect rect(0.0f, 0.0f, ceil(fColumns * fCellSize), Bounds().bottom); 
    364  
     422         
    365423        rgb_color noTint = ui_color(B_PANEL_BACKGROUND_COLOR), 
    366424        lightenmax = tint_color(noTint, B_LIGHTEN_MAX_TINT), 
    367425        darken1 = tint_color(noTint, B_DARKEN_1_TINT), 
    368426        darken4 = tint_color(noTint, B_DARKEN_4_TINT); 
    369  
     427                 
     428        BRect bevelRect = fPaletteFrame.InsetByCopy(-2.0,-2.0); //bevel 
     429         
    370430        // First bevel 
    371431        target->SetHighColor(darken1); 
    372         target->StrokeLine(rect.LeftBottom(), rect.LeftTop()); 
    373         target->StrokeLine(rect.LeftTop(), rect.RightTop()); 
     432        target->StrokeLine(bevelRect.LeftBottom(), bevelRect.LeftTop()); 
     433        target->StrokeLine(bevelRect.LeftTop(), bevelRect.RightTop()); 
    374434        target->SetHighColor(lightenmax); 
    375         target->StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), rect.RightBottom()); 
    376         target->StrokeLine(rect.RightBottom(), BPoint(rect.right, rect.top + 1.0f)); 
     435        target->StrokeLine(BPoint(bevelRect.left + 1.0f, bevelRect.bottom), bevelRect.RightBottom()); 
     436        target->StrokeLine(bevelRect.RightBottom(), BPoint(bevelRect.right, bevelRect.top + 1.0f)); 
    377437 
    378         rect.InsetBy(1.0f, 1.0f); 
     438        bevelRect.InsetBy(1.0f, 1.0f); 
    379439 
    380440        // Second bevel 
    381441        target->SetHighColor(darken4); 
    382         target->StrokeLine(rect.LeftBottom(), rect.LeftTop()); 
    383         target->StrokeLine(rect.LeftTop(), rect.RightTop()); 
     442        target->StrokeLine(bevelRect.LeftBottom(), bevelRect.LeftTop()); 
     443        target->StrokeLine(bevelRect.LeftTop(), bevelRect.RightTop()); 
    384444        target->SetHighColor(noTint); 
    385         target->StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), rect.RightBottom()); 
    386         target->StrokeLine(rect.RightBottom(), BPoint(rect.right, rect.top + 1.0f)); 
     445        target->StrokeLine(BPoint(bevelRect.left + 1.0f, bevelRect.bottom), bevelRect.RightBottom()); 
     446        target->StrokeLine(bevelRect.RightBottom(), BPoint(bevelRect.right, bevelRect.top + 1.0f)); 
     447         
     448        if (fPaletteMode) { 
     449                               
     450        int colBegin = max_c(0, -1 + int(update.left) / int(fCellSize)); 
     451        int colEnd = min_c(fColumns, 2 + int(update.right) / int(fCellSize)); 
     452        int rowBegin = max_c(0, -1 + int(update.top) / int(fCellSize)); 
     453        int rowEnd = min_c(fRows, 2 + int(update.bottom) / int(fCellSize)); 
     454         
     455        //grid 
     456                target->SetHighColor(darken1);           
     457                for (int xi = 0; xi < fColumns+1; xi++){ 
     458                        float x = fPaletteFrame.left + float(xi) * fCellSize; 
     459                        target->StrokeLine(BPoint(x, fPaletteFrame.top), BPoint(x, fPaletteFrame.bottom));                               
     460                } 
     461                for (int yi = 0; yi < fRows+1; yi++){ 
     462                        float y = fPaletteFrame.top + float(yi) * fCellSize; 
     463                        target->StrokeLine(BPoint(fPaletteFrame.left, y), BPoint(fPaletteFrame.right, y));                               
     464                }  
     465                     
     466        //colors                 
     467        for (int col = colBegin; col < colEnd; col++){ 
     468                 
     469                for (int row = rowBegin; row < rowEnd; row++){   
     470                                         
     471                        uint8 colorIndex = row * fColumns + col; 
     472                        float x = fPaletteFrame.left + col * fCellSize; 
     473                                float y = fPaletteFrame.top + row * fCellSize; 
     474                                 
     475                        target->SetHighColor(system_colors()->color_list[colorIndex]); 
     476                                target->FillRect(BRect(x+1, y+1, x + fCellSize - 1, y + fCellSize - 1)); 
     477                }                
     478        }                                         
     479                 
     480        } else { 
     481                 
     482                rgb_color white = {255, 255, 255, 255}; 
     483                rgb_color red = {255, 0, 0, 255}; 
     484                rgb_color green = {0, 255, 0, 255}; 
     485                rgb_color blue = {0, 0, 255, 255}; 
     486                         
     487                _ColorRamp(_RampFrame(0), target, white, 0, false, update);      
     488                _ColorRamp(_RampFrame(1), target, red, 0, false, update);        
     489                _ColorRamp(_RampFrame(2), target, green, 0, false, update);      
     490                _ColorRamp(_RampFrame(3), target, blue, 0, false, update);               
     491        } 
     492         
     493        ConstrainClippingRegion(NULL); 
     494} 
    387495 
    388         // Ramps 
    389         rgb_color white = {255, 255, 255, 255}; 
    390         rgb_color red = {255, 0, 0, 255}; 
    391         rgb_color green = {0, 255, 0, 255}; 
    392         rgb_color blue = {0, 0, 255, 255}; 
    393496 
    394         rect.InsetBy(1.0f, 1.0f); 
    395  
    396         BRect rampRect(rect); 
    397         float rampSize = rampRect.Height() / 4.0; 
    398  
    399         rampRect.bottom = rampRect.top + rampSize; 
    400  
    401         _ColorRamp(rampRect, target, white, 0, false); 
    402  
    403         rampRect.OffsetBy(0, rampSize); 
    404         _ColorRamp(rampRect, target, red, 0, false); 
    405  
    406         rampRect.OffsetBy(0,rampSize); 
    407         _ColorRamp(rampRect, target, green, 0, false); 
    408  
    409         rampRect.OffsetBy(0, rampSize); 
    410         _ColorRamp(rampRect, target, blue, 0, false); 
    411  
    412         // Selectors 
    413         rgb_color color = ValueAsColor(); 
    414         float x, y = rampSize * 1.5; 
    415  
    416         target->SetDrawingMode(B_OP_OVER); 
    417         target->SetPenSize(2.0f); 
    418  
    419         x = rect.left + color.red * (rect.Width() - 7) / 255; 
    420         target->SetHighColor(255, 255, 255); 
    421         target->StrokeEllipse(BRect(x, y, x + 4.0f, y + 4.0f)); 
    422  
    423         y += rampSize; 
    424  
    425         x = rect.left + color.green * (rect.Width() - 7) / 255; 
    426         target->SetHighColor(255, 255, 255); 
    427         target->StrokeEllipse(BRect(x, y, x + 4.0f, y + 4.0f)); 
    428  
    429         y += rampSize; 
    430  
    431         x = rect.left + color.blue * (rect.Width() - 7) / 255; 
    432         target->SetHighColor(255, 255, 255); 
    433         target->StrokeEllipse(BRect(x, y, x + 4.0f, y + 4.0f)); 
    434  
    435         target->SetPenSize(1.0f); 
    436         target->SetDrawingMode(B_OP_COPY); 
    437  
    438         target->ConstrainClippingRegion(NULL); 
     497void 
     498BColorControl::_DrawSelectors(BView* target) 
     499{ 
     500        rgb_color noTint = ui_color(B_PANEL_BACKGROUND_COLOR); 
     501        rgb_color lightenmax = tint_color(noTint, B_LIGHTEN_MAX_TINT); 
     502         
     503         
     504        if (fPaletteMode) { 
     505                if (fSelectedPaletteColorIndex != -1) {                          
     506                target->SetHighColor(lightenmax); 
     507                        target->StrokeRect(_PaletteSelectorFrame(fSelectedPaletteColorIndex)); 
     508                } 
     509                                 
     510        } else {                         
     511                 
     512                rgb_color color = ValueAsColor();                        
     513                target->SetPenSize(kSelectorPenSize);            
     514                target->SetHighColor(255, 255, 255); 
     515                 
     516                target->StrokeEllipse(_SelectorPosition(_RampFrame(1), color.red), 
     517                         kSelectorSize / 2, kSelectorSize / 2);          
     518                target->StrokeEllipse(_SelectorPosition(_RampFrame(2), color.green), 
     519                         kSelectorSize / 2, kSelectorSize / 2);                  
     520                target->StrokeEllipse(_SelectorPosition(_RampFrame(3), color.blue), 
     521                         kSelectorSize / 2, kSelectorSize / 2);  
     522                          
     523                target->SetPenSize(1.0f);                
     524        } 
    439525} 
    440526 
    441527 
    442528void 
    443529BColorControl::_ColorRamp(BRect rect, BView* target, 
    444         rgb_color baseColor, int16 flag, bool focused) 
     530        rgb_color baseColor, int16 flag, bool focused, BRect update) 
    445531{ 
    446         float width = rect.Width()+1; 
     532        float width = rect.Width() + 1; 
    447533        rgb_color color; 
    448534        color.alpha = 255; 
     535         
     536        update = update & rect; 
    449537 
    450         target->BeginLineArray((int32)width); 
     538        if (update.IsValid() && update.Width() >= 0){            
     539                target->BeginLineArray((int32)update.Width() + 1); 
     540         
     541                for (float i = (update.left - rect.left); i <= (update.right - rect.left) + 1; i++) { 
     542                        color.red = (uint8)(i * baseColor.red / width); 
     543                        color.green = (uint8)(i * baseColor.green / width); 
     544                        color.blue = (uint8)(i * baseColor.blue / width); 
     545         
     546                        target->AddLine(BPoint(rect.left + i, rect.top), 
     547                                BPoint(rect.left + i, rect.bottom - 1), color);                  
     548                } 
     549         
     550                target->EndLineArray(); 
     551        } 
     552} 
    451553 
    452         for (float i = 0; i <= width; i++) { 
    453                 color.red = (uint8)(i * baseColor.red / width); 
    454                 color.green = (uint8)(i * baseColor.green / width); 
    455                 color.blue = (uint8)(i * baseColor.blue / width); 
    456554 
    457                 target->AddLine(BPoint(rect.left + i, rect.top), 
    458                         BPoint(rect.left + i, rect.bottom), color); 
    459         } 
     555BPoint 
     556BColorControl::_SelectorPosition(const BRect& rampRect, uint8 shade) const 
     557{ 
     558        float radius = kSelectorSize / 2 + kSelectorPenSize / 2; 
     559         
     560        return BPoint(rampRect.left + kSelectorHSpacing + radius +  
     561                shade * (rampRect.Width() - 2 * (kSelectorHSpacing + radius)) / 255, 
     562                rampRect.top + rampRect.Height() / 2); 
     563} 
    460564 
    461         target->EndLineArray(); 
     565 
     566BRect 
     567BColorControl::_RampFrame(uint8 rampIndex) const 
     568{ 
     569        float rampHeight = 2 * fCellSize;        
     570                         
     571        return BRect( fPaletteFrame.left, 
     572                fPaletteFrame.top + float(rampIndex) * rampHeight, 
     573                fPaletteFrame.right, 
     574                fPaletteFrame.top + float(rampIndex + 1) * rampHeight); 
    462575} 
    463576 
    464577 
     578BRect 
     579BColorControl::_PaletteSelectorFrame(uint8 colorIndex) const 
     580{ 
     581        uint32 row = colorIndex / fColumns; 
     582        uint32 column = colorIndex % fColumns; 
     583        float x = fPaletteFrame.left + column * fCellSize; 
     584        float y = fPaletteFrame.top + row * fCellSize;           
     585        return BRect(x, y, x + fCellSize, y + fCellSize); 
     586} 
     587 
     588 
    465589void 
    466 BColorControl::_UpdateOffscreen(BRect update) 
     590BColorControl::_InitOffscreen() 
    467591{ 
    468         if (fBitmap->Lock()) { 
    469                 update = update & fOffscreenView->Bounds(); 
    470                 fOffscreenView->FillRect(update); 
    471                 _DrawColorArea(fOffscreenView, update); 
     592        if (fBitmap->Lock()) {                   
     593                _DrawColorArea(fOffscreenView, fPaletteFrame.InsetByCopy(-2.0f,-2.0f)); 
    472594                fOffscreenView->Sync(); 
    473595                fBitmap->Unlock(); 
    474596        } 
     
    478600void 
    479601BColorControl::SetCellSize(float cellSide) 
    480602{ 
    481         fCellSize = max_c(kMinCellSize, cellSide); 
    482  
     603        fCellSize = ceil(max_c(kMinCellSize, cellSide)); 
     604        //TODO: update fPaletteFrame here? 
    483605        ResizeToPreferred(); 
    484606} 
    485607 
     
    516638                        fRows = 4; 
    517639                        break; 
    518640        } 
     641         
     642        //TODO: update fPaletteFrame here? 
    519643 
    520644        ResizeToPreferred(); 
    521645        Invalidate(); 
     
    566690void 
    567691BColorControl::MouseDown(BPoint point) 
    568692{ 
    569         BRect rect(0.0f, 0.0f, fColumns * fCellSize, Bounds().bottom); 
    570         if (!rect.Contains(point)) 
     693        if (!fPaletteFrame.Contains(point)) 
    571694                return; 
    572  
    573         rgb_color color = ValueAsColor(); 
    574  
    575         float rampsize = rect.bottom / 4; 
    576  
    577         uint8 shade = (unsigned char)max_c(0, 
    578                 min_c((point.x - 2) * 255 / (rect.Width() - 4.0f), 255)); 
    579  
    580         if (point.y - 2 < rampsize) { 
    581                 color.red = color.green = color.blue = shade; 
    582                 fFocusedComponent = 1; 
    583         } else if (point.y - 2 < (rampsize * 2)) { 
    584                 color.red = shade; 
    585                 fFocusedComponent = 2; 
    586         } else if (point.y - 2 < (rampsize * 3)) { 
    587                 color.green = shade; 
    588                 fFocusedComponent = 3; 
    589         } else { 
    590                 color.blue = shade; 
    591                 fFocusedComponent = 4; 
     695         
     696        if (fPaletteMode) {      
     697                                 
     698        int column = (int) ( (point.x - fPaletteFrame.left) / fCellSize ); 
     699                int row = (int) ( (point.y - fPaletteFrame.top) / fCellSize ); 
     700        int colorIndex = row * fColumns + column; 
     701        if (colorIndex >= 0 && colorIndex < 256) {                       
     702                fSelectedPaletteColorIndex = colorIndex; 
     703                SetValue(system_colors()->color_list[colorIndex]); 
     704        }  
     705         
     706        } else {                 
     707         
     708                rgb_color color = ValueAsColor(); 
     709         
     710                uint8 shade = (unsigned char)max_c(0, 
     711                         min_c((point.x - _RampFrame(0).left) * 255 / _RampFrame(0).Width(), 255)); 
     712                                 
     713                if (_RampFrame(0).Contains(point)) { 
     714                        color.red = color.green = color.blue = shade; 
     715                        fFocusedComponent = 1; 
     716                } else if (_RampFrame(1).Contains(point)) { 
     717                        color.red = shade; 
     718                        fFocusedComponent = 2; 
     719                } else if (_RampFrame(2).Contains(point)) { 
     720                        color.green = shade; 
     721                        fFocusedComponent = 3; 
     722                } else if (_RampFrame(3).Contains(point)){ 
     723                        color.blue = shade; 
     724                        fFocusedComponent = 4; 
     725                } 
     726                 
     727                SetValue(color); 
     728                 
    592729        } 
    593  
    594         SetValue(color); 
     730         
    595731        Invoke(); 
    596732 
    597733        SetTracking(true); 
     
    604740BColorControl::MouseMoved(BPoint point, uint32 transit, 
    605741        const BMessage *message) 
    606742{ 
    607         if (fFocusedComponent == 0 || !IsTracking()) 
    608                 return; 
     743        if (!IsTracking()) 
     744                return;  
     745                 
     746        if (fPaletteMode && fPaletteFrame.Contains(point)) {     
     747                                 
     748        int column = (int) ( (point.x - fPaletteFrame.left) / fCellSize ); 
     749                int row = (int) ( (point.y - fPaletteFrame.top) / fCellSize ); 
     750        int colorIndex = row * fColumns + column; 
     751        if (colorIndex >= 0 && colorIndex < 256) { 
     752                fSelectedPaletteColorIndex = colorIndex; 
     753                SetValue(system_colors()->color_list[colorIndex]);                       
     754        }  
     755         
     756        } else {                 
    609757         
    610         rgb_color color = ValueAsColor(); 
    611  
    612         BRect rect(0.0f, 0.0f, fColumns * fCellSize, Bounds().bottom); 
    613  
    614         uint8 shade = (unsigned char)max_c(0, 
    615                 min_c((point.x - 2) * 255 / (rect.Width() - 4.0f), 255));