⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ylscrollwidget.c

📁 滑动控件的使用哈,只是测试用, 一起共享受一下资源是!
💻 C
字号:


#include "YLScrollWidget.h"
#include "AEEWProperties.h"
#include "wutil.h"
#include "widget_res.h"
#include "AEEDisplayCanvas.h"


//#define SBBORDER_WIDTH     1 //modified by 曾念荣
#define SBBORDER_WIDTH     0
#define SBWIDTH            (me->nHandleWidth + (2 * SBBORDER_WIDTH))
#define SBARROW_HEIGHT     10  //单个箭头的高度(含箭头外面的矩形框)

#define DEFAULT_YLSCROLLBORDER_COLOR MAKE_RGBA(0, 0, 0, 255);
#define DEFAULT_YLSCROLLHANDLE_COLOR MAKE_RGBA(97, 97, 97, 255);

static __inline YLScrollbarWidget *DECORATOR_TO_YLSCROLLBARWIDGET(IDecorator *po) {
   return (YLScrollbarWidget*)po;
}
static __inline YLScrollbarWidget *CONTAINER_TO_YLSCROLLBARWIDGET(IContainer *po) {
   return (YLScrollbarWidget*)po->pMe;
}



#define YLSCROLLBAR_FROM_DECORATOR YLScrollbarWidget *me = DECORATOR_TO_YLSCROLLBARWIDGET(po)
#define YLSCROLLBAR_FROM_CONTAINER YLScrollbarWidget *me = CONTAINER_TO_YLSCROLLBARWIDGET(po)

// compute scrollbar handle size
//
// The ratio of the scrollbar handle's size to the total
// scrollbar size is the same as the ratio of the
// ScrollEvent's visible member to its total range.  That
// is:
//
//  scrollbar handle (c)        visible (v)
// ----------------------  ==  ------------
//  total scrollbar (d)          range (r)
//
// So:
//
//    c = d * (v / r)
//
static __inline uint16 YLScrollbarWidget_ComputeSize(uint32 d, uint32 r, uint32 v)
{
   uint32 c = 0;

   // non-zero range must have been specified
   if (r > 0) {
      c = (d * v) / r;
   }

   return (uint16)c;
}

// compute scrollbar handle position 
//
// Valid handle pixel positions (c) are within the range of 0 
// to the total scrollbar size (d) minus the scrollbar handle
// size.   0 < c < ScrollbarWidget_ComputeSize(d, r, v)
//
// The ScrollEvent's position (p) falls with the same range of 0
// to the total range (r) minus the visible (v).  0 < p < r - v.
// Any position beyond that range is treated as fully scrolled.
//
// To set the scroll handle to its maximum position, p >= r-v.
// 
// For all other positions, the ratio of the pixel position of
// the handle (c) to the total pixel range of the scroll bar handle
// (d - ScrollbarWidget_ComputeSize(d, r, v)) is the same as the 
// ratio of the ScrollEvent's position (p) to the total scroll range 
// minus the visisible (d - v).  That is:
//
// c / (d - ScrollbarWidget_ComputeSize(d, r, v)) == p / (r - v)
//
// So: 
//
// c = (p * (d - ScrollbarWidget_ComputeSize(d, r, v))) / (r - v)
//
// This can be simplified as follows:
//
// c = (p * (d - (d * v/r)) / (r - v)
//
// c = (p * ((dr - dv)/r) / (r - v)
//
// c = (p * d * (r - v) * (1 / r) * 1/(r- v)
//
// Ultimately, the scoll handle's pixel position can be computed
// from the total scroll bar pixel size (d), the ScrollEvent's
// position (p) and the ScrollEvent's total range (r) as:
//
// c = p * d / r
//
static __inline uint16 YLScrollbarWidget_ComputePosition(uint32 d, uint32 p, uint32 r, uint32 v) 
{
   uint32 c = 0;

   // non-zero range must have been specified
   if (r > 0) {
      // scrollbar is 100& scrolled if position is greater than or equal to range - visible.
      if (p >= (r - v)) {
         // 100% scrolled, make sure scroll bar is at the bottom for any value
         // of p beyond (r - v).
         c = d - (d * v / r);
      } else {
         // compute scrollbar position.  Do our best to avoid overflow and roundoff errors.  
         // Position, range and visible may be large or small, so let's assume the worst.
         c = p * d;
         c /= r;
      }
   }

   return (uint16)c;
}


void YLScrollbarWidget_Ctor(YLScrollbarWidget *me, AEEVTBL(IDecorator) *pvt, IShell *piShell, 
                          IModule *piModule, PFNHANDLER pfnDefHandler)
{
	ScrollbarWidget* psb = (ScrollbarWidget*)me;

	ScrollbarWidget_Ctor(psb, pvt, piShell, piModule, pfnDefHandler);

   me->rgbStartBlank    = MAKE_RGB(230,230,230);
   me->rgbStartHandle   = MAKE_RGB(230,230,230);
   me->rgbStartArrow    = MAKE_RGB(230,230,230);
   me->nGradientStyle   = GRADIENT_STYLE_HORZ;//颜色水平渐变

   psb->rgbBorder[RGBINDEX_ACTIVE]   = MAKE_RGB(111,125,79); 
   psb->rgbBorder[RGBINDEX_INACTIVE] = MAKE_RGB(158,173,150); 
   
   psb->rgbHandle[RGBINDEX_ACTIVE]   = 
   psb->rgbHandle[RGBINDEX_INACTIVE] = DEFAULT_YLSCROLLHANDLE_COLOR; 

   psb->rgbFill = RGB_WHITE;

   psb->nHandleWidth = 11;
   psb->nPad = 0;
   psb->nEndPad = 0;

   pvt->Draw =  YLScrollbarWidget_Draw;
}

int YLScrollbarWidget_New(IDecorator **ppo, IShell *piShell, IModule *piModule)
{
   YLScrollbarWidget *me = MALLOCREC_VTBL(YLScrollbarWidget, IDecorator);
   if (!me)
      return ENOMEMORY;

   YLScrollbarWidget_Ctor(me, GETVTBL(me,IDecorator), piShell, piModule, 0);

   *ppo = YLSCROLLBARWIDGET_TO_IDECORATOR(me);

   return 0;
}

void YLSbArrows_DrawVertArrows(SbArrows *me, IDisplay *piDisplay, AEERect *prc, 
                                    RGBVAL rgbUp, RGBVAL rgbDown, boolean bReduce,
                                    int nEndPad)
{
   AEERect rcLine;
   int x, y;

   // ensure resource image is loaded
   if (!TILEDIMAGE_HASIMAGE(&me->tiVArrows) && 
       me->piShell && 
       0 != TiledImage_LoadResBitmap(&me->tiVArrows, me->piShell, "widgets.mif", IDB_VSBARROWS, 2)) {
      return;
   }

   x = prc->x + ((prc->dx - me->tiVArrows.cxTile) / 2);
   y = prc->y;
   if (rgbUp != RGB_NONE) {
      //TiledImage_ReplaceColor(&me->tiVArrows, RGB_BLACK, rgbUp);
      //TiledImage_DrawTile(&me->tiVArrows, piDisplay, x, y, 0);
      TiledImage_DrawTile(&me->tiVArrows, piDisplay, x, y+4, 0);
   }

   rcLine.x = prc->x+1;
   rcLine.y = prc->y;
   rcLine.dx = prc->dx - 2;
   rcLine.dy = 1;
   IDISPLAY_DrawRect(piDisplay, &rcLine, RGB_NONE, rgbUp, IDF_RECT_FILL);//上边线

   rcLine.y = prc->y + SBARROW_HEIGHT - 1;
   IDISPLAY_DrawRect(piDisplay, &rcLine, RGB_NONE, rgbUp, IDF_RECT_FILL);//下边线

   rcLine.x = prc->x;
   rcLine.y = prc->y + 1;
   rcLine.dx = 1;
   rcLine.dy = SBARROW_HEIGHT - 2;
   IDISPLAY_DrawRect(piDisplay, &rcLine, RGB_NONE, rgbUp, IDF_RECT_FILL);//左边线

   rcLine.x = prc->x + prc->dx -1;
   IDISPLAY_DrawRect(piDisplay, &rcLine, RGB_NONE, rgbUp, IDF_RECT_FILL);//右边线

   //y = prc->y + prc->dy - me->tiVArrows.cyTile;
   y = prc->y + prc->dy - SBARROW_HEIGHT;
   if (rgbDown != RGB_NONE) {
      //TiledImage_ReplaceColor(&me->tiVArrows, RGB_BLACK, rgbDown);
      //TiledImage_DrawTile(&me->tiVArrows, piDisplay, x, y, 1);
      TiledImage_DrawTile(&me->tiVArrows, piDisplay, x, y+3, 1);
   }

   rcLine.x = prc->x+1;
   rcLine.y = y;
   rcLine.dx = prc->dx - 2;
   rcLine.dy = 1;
   IDISPLAY_DrawRect(piDisplay, &rcLine, RGB_NONE, rgbUp, IDF_RECT_FILL);//上边线

   rcLine.y = y + SBARROW_HEIGHT - 1;
   IDISPLAY_DrawRect(piDisplay, &rcLine, RGB_NONE, rgbUp, IDF_RECT_FILL);//下边线

   rcLine.x = prc->x;
   rcLine.y = y + 1;
   rcLine.dx = 1;
   rcLine.dy =  SBARROW_HEIGHT- 2;
   IDISPLAY_DrawRect(piDisplay, &rcLine, RGB_NONE, rgbUp, IDF_RECT_FILL);//左边线

   rcLine.x = prc->x + prc->dx -1;
   IDISPLAY_DrawRect(piDisplay, &rcLine, RGB_NONE, rgbUp, IDF_RECT_FILL);//右边线

   if (bReduce) {
      //INFLATERECT(prc, 0, -(MAX(nEndPad, me->tiVArrows.cyTile+1)));
      INFLATERECT(prc, 0, -SBARROW_HEIGHT);
   }
}


void YLScrollbarWidget_Draw(IDecorator *po, ICanvas *piCanvas, int x, int y)
{

   YLSCROLLBAR_FROM_DECORATOR;
   ScrollbarWidget* psb = &me->base;
   AEERect rc;
   AEERect rcFill;
   IDisplay *piDisplay = 0;

   RGBVAL rgbBorder = psb->rgbBorder[psb->border.bActive];

   Border_Draw(&psb->border, piCanvas, x, y);

   if (SUCCESS != ICANVAS_GetDisplay(piCanvas, &piDisplay)) {
      return;
   }

   if (psb->nScrollStyle == SCROLL_VERT || psb->nScrollStyle == SCROLL_BOTH) {

      // Get scrollbar rect            
      ScrollbarWidget_GetScrollbarRect(psb, 0, &rc);

      if (rc.dx && rc.dy) {
         ScrollInfo *psi = &psb->scroll[SCROLL_VERT];
   
         // inset by drawing location
         rc.x += x;
         rc.y += y;
   
         //if (psb->dwFlags & SBWF_ARROWS) {
         if ((psb->dwFlags & SBWF_ARROWS) && (rc.dy > SBARROW_HEIGHT*4)) {//绘画区域高度大于4倍的箭头高度
            YLSbArrows_DrawVertArrows(&psb->arrows, piDisplay, &rc, rgbBorder, rgbBorder, 1, 
                                    psb->nEndPad);//箭头
         } else {
            INFLATERECT(&rc, 0, -psb->nEndPad);
         }


  //不需要画边框 曾念荣
/*         if (rgbBorder != RGBA_NONE) {
            DrawAndInsetBorder(piDisplay, &rc, SBBORDER_WIDTH, rgbBorder);//画边框
         }
*/
      
         //IDISPLAY_DrawRect(piDisplay, &rc, RGB_NONE, RGBA_STRIPALPHA(psb->rgbFill), IDF_RECT_FILL);//填充空白处
		 //IDISPLAY_DrawRect(piDisplay, &rcFill, RGB_NONE, RGBA_STRIPALPHA(psb->rgbFill), IDF_RECT_FILL);//填充空白处
   
		 IDisplay_FillRectGradient(piDisplay, &rc, me->rgbStartBlank, psb->rgbFill, 0, 0, 1);//填充空白处
		 
         if (psi->range > psi->visible) 
         {
            int dyMin = MIN(4, rc.dy);
            int yMax = rc.y + rc.dy;

            if((psb->dwFlags & SBWF_FOCUSTRACK) && psb->numItems > 0) {
               rc.y += (rc.dy * psb->focusIndex) / psb->numItems;
               rc.dy = rc.dy / psb->numItems;
            }
            else {
               rc.y += YLScrollbarWidget_ComputePosition(rc.dy, psi->position, psi->range, psi->visible);
               rc.dy = YLScrollbarWidget_ComputeSize(rc.dy, psi->range, psi->visible);
            }

            rc.dy = MAX(dyMin, rc.dy);
            rc.y = MIN(rc.y, yMax - rc.dy);
   
            //IDISPLAY_DrawRect(piDisplay, &rc, RGB_NONE, RGBA_STRIPALPHA(psb->rgbHandle[psb->border.bActive]), IDF_RECT_FILL);
            IDisplay_FillRectGradient(piDisplay, &rc, me->rgbStartHandle, RGBA_STRIPALPHA(psb->rgbHandle[psb->border.bActive]), 0, 0, 1);

            //add by 曾念荣 2006.5.23 
            //画滑块边框
            rcFill.y    = rc.y;
            rcFill.dy   = 1;
            rcFill.x    = rc.x+1;
            rcFill.dx   = rc.dx - 2;
            IDISPLAY_DrawRect(piDisplay, &rcFill, RGB_NONE, RGBA_STRIPALPHA(psb->rgbHandle[psb->border.bActive]), IDF_RECT_FILL);//上边线

            rcFill.y = rc.y + rc.dy-1;
            IDISPLAY_DrawRect(piDisplay, &rcFill, RGB_NONE, RGBA_STRIPALPHA(psb->rgbHandle[psb->border.bActive]), IDF_RECT_FILL);//下边线

            rcFill.x = rc.x;
            rcFill.y = rc.y +1;
            rcFill.dx = 1;
            rcFill.dy = rc.dy -2;
            IDISPLAY_DrawRect(piDisplay, &rcFill, RGB_NONE, RGBA_STRIPALPHA(psb->rgbHandle[psb->border.bActive]), IDF_RECT_FILL);//左边线

            rcFill.x = rc.x + rc.dx-1;
            IDISPLAY_DrawRect(piDisplay, &rcFill, RGB_NONE, RGBA_STRIPALPHA(psb->rgbHandle[psb->border.bActive]), IDF_RECT_FILL);//右边线
            //end add
         }
      }
   }

   //不需要支持横向的滚动条。
/*   if (psb->nScrollStyle == SCROLL_HORZ || psb->nScrollStyle == SCROLL_BOTH) {

      ScrollbarWidget_GetScrollbarRect(psb, 1, &rc);

      if (rc.dx && rc.dy) {
         ScrollInfo *psi = &psb->scroll[SCROLL_HORZ];
   
         // Get scrollbar rect 
         // inset by drawing location
         rc.x += x;
         rc.y += y;
   
         if (psb->dwFlags & SBWF_ARROWS) {
            SbArrows_DrawHorzArrows(&psb->arrows, piDisplay, &rc, rgbBorder, rgbBorder, 1,
                                    psb->nEndPad);
         } else {
            INFLATERECT(&  rc, -psb->nEndPad, 0);
         }
   
         if (rgbBorder != RGBA_NONE) {
            DrawAndInsetBorder(piDisplay, &rc, SBBORDER_WIDTH, rgbBorder);
         }
      
         IDISPLAY_DrawRect(piDisplay, &rc, RGB_NONE, RGBA_STRIPALPHA(psb->rgbFill), IDF_RECT_FILL);
   
         if (psi->range > psi->visible) {
            int dxMin = MIN(4, rc.dx);

            if((psb->dwFlags & SBWF_FOCUSTRACK) && psb->numItems > 0) {
               rc.x += (rc.dx * psb->focusIndex) / psb->numItems;
               rc.dx = rc.dx / psb->numItems;
            }
            else {
               rc.x += YLScrollbarWidget_ComputePosition(rc.dx, psi->position, psi->range, psi->visible);
               rc.dx = YLScrollbarWidget_ComputeSize(rc.dx, psi->range, psi->visible);
            }
   
            rc.dx = MAX(dxMin, rc.dx);

            IDISPLAY_DrawRect(piDisplay, &rc, RGB_NONE, RGBA_STRIPALPHA(psb->rgbHandle[psb->border.bActive]), IDF_RECT_FILL);
         }
      }
   }
*/
   RELEASEIF(piDisplay);

   Decorator_Draw(po, piCanvas, psb->border.rcClient.x + x, psb->border.rcClient.y + y);

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -