уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

В принципе вопрос о том, как создать свою «неповторимую» ленту Ribbon я частично рассматривал в одном из постов, посвященных Ribbon Controls в Delphi. Однако, ряд моментов, касающихся разработке своего скина для Ribbon все же стоит рассмотреть по-подробнее. В частности процесс отрисовки скина.

Во-первых, если Вы решили создать что-то неповторимое и уникальное в плане цветовой палитры, например, сделать ленту не голубой, а, скажем, розовой (гламур :)), то при работе с bmp-файлом скина следует очень осторожно раскрашивать все элементы — отклонение в пиксел уже может привести к тому, что на выходе в рабочей программе вы получите нечно действительно уникальное, но в плохом смысле — скин будет «кривой».
Во-вторых, если Вы решили рисовать свой скин «с нуля», то следует обратить внимание на вот этот класс:

TRibbonStyleActionBars = class(TXPStyleActionBars)

из модуля RibbonStyleActnCtrls.pas. Так как именно здесь содержатся все необходимые методы «отрисовки» скина по заданному файлу (bmp или res).
в TRibbonStyleActionBars кроме всего прочьего содержится ряд overload-методов, каждый из которых определяет границы прямоугольника в котором содержится изображаемый элемент ленты. Например, вот метод, реализующий отрисовку группы:

procedure TRibbonStyleActionBars.DrawElement(Element: TSkinRibbonGroup;
  Canvas: TCanvas; Rect: TRect);
var
  LSrcRect: TRect;
  LDstRect: TRect;
begin
  if Element = srgBackground then
  begin
    LSrcRect := Types.Rect(225, 504, 225 + 20, 504 + 86);
    DrawButton(RibbonSkin.Bitmap, LSrcRect, Canvas, Rect, 3, 3, 255);
  end
  else if Element = srgBackgroundHover then
  begin
    LSrcRect := Types.Rect(204, 504, 204 + 20, 504 + 86);
    DrawButton(RibbonSkin.Bitmap, LSrcRect, Canvas, Rect, 3, 3, 255);
  end
  else if Element = srgBackgroundDisabled then
  begin
    LSrcRect := Types.Rect(246, 504, 246 + 20, 504 + 86);
    DrawButton(RibbonSkin.Bitmap, LSrcRect, Canvas, Rect, 3, 3, 255);
  end
  else if Element = srgMinimizeButton then
  begin
    LSrcRect := Types.Rect(275, 208, 275 + 40, 208 + 86);
    DrawButton(RibbonSkin.Bitmap, LSrcRect, Canvas, Rect, 3, 3, 255);
  end
  else if Element = srgMinimizeButtonHover then
  begin
    LSrcRect := Types.Rect(315, 208, 315 + 40, 208 + 85);
    DrawButton(RibbonSkin.Bitmap, LSrcRect, Canvas, Rect, 3, 3, 255);
  end
  else if Element = srgMinimizeButtonPressed then
  begin
    LSrcRect := Types.Rect(355, 208, 355 + 40, 208 + 85);
    DrawButton(RibbonSkin.Bitmap, LSrcRect, Canvas, Rect, 3, 3, 255);
  end
  else if Element in [srgCaption, srgCaptionHover, srgCaptionDisabled] then
  begin
    if Element = srgCaptionHover then
      LSrcRect := Types.Rect(206, 573, 206 + 16, 573 + 11)
    else if Element = srgCaptionDisabled then
      LSrcRect := Types.Rect(248, 573, 248 + 16, 573 + 12)
    else
      LSrcRect := Types.Rect(227, 573, 227 + 16, 573 + 12);
    Rect.Bottom := Rect.Bottom - 4;
    DrawTransparentBitmap(RibbonSkin.Bitmap, LSrcRect, Canvas, Rect);
  end
  else if Element = srgDialogButton then
  begin
    LSrcRect := Types.Rect(329, 167, 329 + 15, 167 + 14);
    DrawTransparentBitmap(RibbonSkin.Bitmap, LSrcRect, Canvas, Rect);
  end
  else if Element = srgDialogButtonHover then
  begin
    LSrcRect := Types.Rect(344, 167, 344 + 15, 167 + 14);
    DrawTransparentBitmap(RibbonSkin.Bitmap, LSrcRect, Canvas, Rect);
  end
  else if Element = srgDialogButtonPressed then
  begin
    LSrcRect := Types.Rect(359, 167, 359 + 15, 167 + 14);
    DrawTransparentBitmap(RibbonSkin.Bitmap, LSrcRect, Canvas, Rect);
  end
  else if Element = srgMinimizeButtonIcon then
  begin
    LSrcRect := Types.Rect(396, 208, 396 + 31, 208 + 31);
    LDstRect := Rect;
    LDstRect.Right := LDstRect.Left + 31;
    LDstRect.Bottom := LDstRect.Top + 31;
    DrawTransparentBitmap(RibbonSkin.Bitmap, LSrcRect, Canvas, LDstRect);
  end
  else if Element = srgMinimizeButtonPressedIcon then
  begin
    LSrcRect := Types.Rect(396, 240, 396 + 31, 240 + 31);
    LDstRect := Rect;
    LDstRect.Right := LDstRect.Left + 31;
    LDstRect.Bottom := LDstRect.Top + 31;
    DrawTransparentBitmap(RibbonSkin.Bitmap, LSrcRect, Canvas, LDstRect);
  end
end;

Element представляет собой простой перечислитель с помощью значений которого можно указать процедуре, что именно нам необходимо нарисовать — неактивную группу, активную (когда курсор мыши находится над ней) и т.д.
Обратите также внимание на обилие констант в процедуре, когда определяется переменная LSrcRect — «исходник» изображаемого объекта. Имеено по этому следует с особой осторожностью заниматься перекраской уже готовых скинов.
Опять же, если вдруг захочется создать скин в котором элементы будут располагаться так как Вам этого хочется, то вновь придётся вернуться к DrawElement и указать что и откуда копировать.
Ну, а дальше выполняется метод DrawButton, который отрисовывает на формеэлемент ленты. При этом вначале проверяются линейные размеры исходного изображения и текущих размеров элемента и если размеры совпадают, то изображение из файла скина переносится «как есть», иначе — «исходник» растягивается (ак, например, отрисовывается основа ленты).

Таким образом, чтобы создать новый скин для Ribbon вам необходимо:
1. Иметь под рукой готовый bmp или res-файл, в котором содержаться изображения всех элементов ленты во всех состояниях (нажат, выделен, неактивен и т.д.)
2. На основании того как располагаются элементы в файле определить методы отрисовки — DrawElement.
3. Воспользоваться рекомендациями из этого поста блога.
В итоге, если всё будет сделано верно и точно получится нормальный уникальный скин для Ribbon.

Кстати, по поводу Ribbon в целом. Было время немного покопаться в Delphi XE, посмотреть, что да как. Так вот, что касается Ribbon Controls — все осталось как и прежде. Так что, если Вы хотите поставить Delphi XE в надежде на то, что Ribbon’ыстали работать лучше — можете даже и не заморачиваться.

0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
2 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
GlooK
12/09/2010 02:54

Было бы замечательно, если вы вставите скрины в пост.

cleaner
cleaner
13/10/2010 11:53

«Кстати, по поводу Ribbon в целом. Было время немного покопаться в Delphi XE, посмотреть, что да как. Так вот, что касается Ribbon Controls – все осталось как и прежде. Так что, если Вы хотите поставить Delphi XE в надежде на то, что Ribbon’ыстали работать лучше – можете даже и не заморачиваться.»
жаль… я XE только для этого и качал