Ticket #8618: dragable-colorwell.patch

File dragable-colorwell.patch, 4.5 KB (added by mks, 7 years ago)
  • src/preferences/appearance/ColorWell.cpp

    diff --git a/src/preferences/appearance/ColorWell.cpp b/src/preferences/appearance/ColorWell.cpp
    index 2a5e5ea..634743d 100644
    a b  
    77 */
    88#include "ColorWell.h"
    99
     10#include <new>
     11#include <stdio.h>
     12
     13#include <Bitmap.h>
     14
     15
     16#define DRAG_INIT_DIST 10.0
     17
     18
    1019ColorWell::ColorWell(BRect frame, BMessage *msg, uint32 resizingMode, uint32 flags)
    11  :  BView(frame,"ColorWell", resizingMode, flags | B_WILL_DRAW)
     20 :  BView(frame,"ColorWell", resizingMode, flags | B_WILL_DRAW),
     21    fTrackingStart(-1.0, -1.0)
    1222{
    1323    SetViewColor(B_TRANSPARENT_COLOR);
    1424    SetLowColor(0,0,0);
    ColorWell::SetMode(bool is_rectangle) 
    139149{
    140150    is_rect=is_rectangle;
    141151}
     152
     153void
     154ColorWell::MouseDown(BPoint where)
     155{
     156    if (Bounds().Contains(where))
     157        fTrackingStart = where;
     158}
     159
     160void
     161ColorWell::MouseUp(BPoint where)
     162{
     163    fTrackingStart.x = -1.0;
     164    fTrackingStart.y = -1.0;
     165}
     166
     167void
     168ColorWell::MouseMoved(BPoint where, uint32 transit,
     169    const BMessage* dragMessage)
     170{
     171    if (Bounds().Contains(fTrackingStart)) {
     172        if (point_point_distance(where, fTrackingStart) > DRAG_INIT_DIST
     173            || transit == B_EXITED_VIEW) {
     174            _DragColor();
     175            fTrackingStart.x = -1.0;
     176            fTrackingStart.y = -1.0;
     177        }
     178    }
     179}
     180
     181void
     182ColorWell::_DragColor()
     183{
     184    BBitmap* bitmap = new(std::nothrow) BBitmap(BRect(0.0, 0.0, 15.0, 15.0),
     185        B_RGB32);
     186
     187    BMessage message = make_color_drop_message(currentcol, bitmap);
     188
     189    DragMessage(&message, bitmap, B_OP_ALPHA, BPoint(9.0, 9.0));
     190}
     191
     192BMessage
     193make_color_drop_message(rgb_color color, BBitmap* bitmap)
     194{
     195    // prepare message
     196    BMessage message(B_PASTE);
     197    char hexString[8];
     198    snprintf(hexString, sizeof(hexString), "#%.2X%.2X%.2X",
     199        color.red, color.green, color.blue);
     200    message.AddData("text/plain", B_MIME_TYPE, &hexString, sizeof(hexString));
     201    message.AddData("RGBColor", B_RGB_COLOR_TYPE, &color, sizeof(color));
     202    // prepare bitmap
     203    if (bitmap && bitmap->IsValid()
     204        && (bitmap->ColorSpace() == B_RGB32
     205            || bitmap->ColorSpace() == B_RGBA32)) {
     206        uint8* bits = (uint8*)bitmap->Bits();
     207        uint32 bpr = bitmap->BytesPerRow();
     208        uint32 width = bitmap->Bounds().IntegerWidth() + 1;
     209        uint32 height = bitmap->Bounds().IntegerHeight() + 1;
     210        for (uint32 y = 0; y < height; y++) {
     211            uint8* bitsHandle = bits;
     212            for (uint32 x = 0; x < width; x++) {
     213                if (x == 0 || y == 0 ) {
     214                    // top or left border
     215                    bitsHandle[0] = (uint8)min_c(255, color.blue * 1.2 + 40);
     216                    bitsHandle[1] = (uint8)min_c(255, color.green * 1.2 + 40);
     217                    bitsHandle[2] = (uint8)min_c(255, color.red * 1.2 + 40);
     218                    bitsHandle[3] = 180;
     219                } else if ((x == width - 2 || y == height - 2)
     220                           && !(x == width - 1 || y == height - 1)) {
     221                    // bottom or right border
     222                    bitsHandle[0] = (uint8)(color.blue * 0.8);
     223                    bitsHandle[1] = (uint8)(color.green * 0.8);
     224                    bitsHandle[2] = (uint8)(color.red * 0.8);
     225                    bitsHandle[3] = 180;
     226                } else if (x == width - 1 || y == height - 1) {
     227                    // shadow
     228                    bitsHandle[0] = 0;
     229                    bitsHandle[1] = 0;
     230                    bitsHandle[2] = 0;
     231                    bitsHandle[3] = 100;
     232                } else {
     233                    // color
     234                    bitsHandle[0] = color.blue;
     235                    bitsHandle[1] = color.green;
     236                    bitsHandle[2] = color.red;
     237                    bitsHandle[3] = 180;
     238                }
     239                if ((x == 0 && y == height - 1) || (y == 0 && x == width - 1)) {
     240                    // spare pixels of shadow
     241                    bitsHandle[0] = 0;
     242                    bitsHandle[1] = 0;
     243                    bitsHandle[2] = 0;
     244                    bitsHandle[3] = 50;
     245                }
     246                bitsHandle += 4;
     247            }
     248            bits += bpr;
     249        }
     250    }
     251    return message;
     252}
     253
  • src/preferences/appearance/ColorWell.h

    diff --git a/src/preferences/appearance/ColorWell.h b/src/preferences/appearance/ColorWell.h
    index 92c2ea5..a408722 100644
    a b public: 
    2727    virtual void SetTarget(BHandler *tgt);
    2828    virtual void SetEnabled(bool value);
    2929    void SetMode(bool is_rectangle);
     30    virtual void MouseDown(BPoint where);
     31    virtual void MouseUp(BPoint where);
     32    virtual void MouseMoved(BPoint where, uint32 transit,
     33                              const BMessage* dragMessage);
    3034protected:
    3135    BInvoker *invoker; 
    3236    bool is_enabled, is_rect;
    3337    rgb_color disabledcol, currentcol;
     38private:
     39    void _DragColor();
     40    BPoint fTrackingStart;
    3441};
    3542
     43
     44// point_point_distance
     45inline float
     46point_point_distance(BPoint a, BPoint b)
     47{
     48    float xDiff = b.x - a.x;
     49    float yDiff = b.y - a.y;
     50    return sqrtf(xDiff * xDiff + yDiff * yDiff);
     51}
     52
     53
     54BMessage make_color_drop_message(rgb_color color, BBitmap* bitmap);
     55
     56
    3657#endif