«Прямо и не знаю, что об этом думать»,
как сказал король Дезмонд, когда его прихватили на шулерстве
(с)Анджей Спаковский, «Ведьмак» часть 7 «Владычица Озера»
Продолжаем копошиться в дебрях и хитросплетениях Ribbon Controls. Сегодня на повестке дня настройка Ribbon Controls для русскоязычного населения плюс немного креатива в плане создания своих тем оформления для Ribbon Controls.
Помниться у кого-то из читателей блога возникал вопрос «Как руссифицировать меню Costumize Dialog?» . Давайте разбираться. Ведь ни с потолка же падают строки и вставляются сами в менюшку?
Самый простой способ решения подобных вопросов – это заглянуть в папку
C:\Program Files\Embarcadero\RAD Studio\7.0\lib\
и посмотреть модуль с названием, наподобие RibbonSrt или RibbonConst. Ведь разработчики должны соблюдать все правила написания программного кода, в том числе и избегать использования строковых и, по возможности, других констант в телах процедур и функций. Открываем папку и действительно наблюдаем там замечательный файлик RibbonConsts.dcu. Одноименный файл, но с расширением *.pas находится в папке
C:\Program Files\Embarcadero\RAD Studio\7.0\source\Win32\vcl\
Перетаскиваем RibbonConsts.pas себе в проект, подключаем в uses и открываем в редакторе кода. Теперь все, что от нас требуется – это грамотно и без ошибок перевести на русский язык все, содержащиеся в модуле строки. Там их немного – всего двадцать четыре штучки.
После руссификации модуля меню будет выглядеть примерно следующим образом:
Как видите, всё просто и не требует особых программистских способностей. Только уменя пользоваться переводчиком.
А теперь переходим к вопросу, которым я, ради собственного нездорового интереса, сейчас сижу и занимаюсь на работе (только бы не пришло начальство), а именно – изменение внешнего вида Ribbon. Или, говоря более понятным языком – создание собственных тем оформления для Ribbon Controls. Неуверен, что смогу так вот сходу за несколько часов во всём разобраться, да ещё и расписать в блоге, но постараюсь выложить как можно больше информации, если что – надеюсь на Вашу помощь в освоении темы. Итак поехали.
Ribbon Skins в Delphi 2010
Начнем изучение темы с того, что наиболее просто – цветовые схемы. В Delphi уже изначально есть три готовых компонента для цветовых схем:
- XPColorMap
- StanderdColorMap
- TwilightColorMap
Попробуем применить их на практике. По логике вещей и, судя по названию свойств у компонентов, в зависимости от цветовой схемы должны меняться цвета шрифтов и тени компонентов как минимум. Проверим на практике. Размещаем на форме, как обычно: ActionManager и Ribbon. Создаем парочку Action в менеджере, у риббона создаем один Tab и две группы (а можно и одну – как Вам угодно) и размещаем в группах наши Action’ы.
Теперь кидаем на форму простой ComboBox, все три доступные цветовые схемы и кнопку. У меня получилась вот такая неказистая формочка:
Теперь добавляем в ComboBox три строки, каждая из которых будет описывать одну из цветовых схем и в обработчике клика по кнопке пишем следующий код
[…] case ComboBox1.ItemIndex of 0:Ribbon1.ColorMap:=XPColorMap1; 1:Ribbon1.ColorMap:=StandardColorMap1; 2:Ribbon1.ColorMap:=TwilightColorMap1; end; Ribbon1.Repaint: […]
Запускаем приложение и проверяем, что получилось. Порадовало, что цвета шрифтов сменились:
Не порадовал глюк с панелью быстрого запуска – обратите на него внимание. Причём как оказалось глюк этот не пропадает даже если перезагрузить Delphi…хотя это может только на рабочей машинке глюк – дома проверю наверняка. А пока продолжим.
Сейчас мы рассмотрели один из вариантов смены цветовой схемы – с использованием стандартных, уже долгое время существующих компонентов цветовых схем.
Но у Ribbon также есть и свой тип TcustomRibbonColorMap в модуле Ribbon. Можно, да и видимо, нужно использовать этот тип данных при работе с цветовыми схемами Ribbon. Попробуем применить его.
После недолгих манипуляций с мышкой форма приложения приняла следующий вид:
Каждый из новых ColorBox будет описывать значение цвета для одного из свойств TcustomRibbonColorMap.
Дописывем обработчик события кнопки:
[…] var Ribbon: TCustomRibbonColorMap; begin case case ComboBox1.ItemIndex of […] 3: begin Ribbon:=TCustomRibbonColorMap.Create(self); With Ribbon do begin BevelMinimizedInner:=ColorBox1.Selected; BevelMinimizedOuter:=ColorBox2.Selected; BtnSelectedFont:=ColorBox3.Selected; CaptionFontColor:=ColorBox4.Selected; ControlColor:=ColorBox5.Selected; ControlInactiveColor:=ColorBox6.Selected; ControlFrameColor:=ColorBox7.Selected; DisabledFontColor:=ColorBox8.Selected; DocumentFontColor:=ColorBox16.Selected; FontColor:=ColorBox15.Selected; HighlightColor:=ColorBox14.Selected; ActiveTabFontColor:=ColorBox13.Selected; GroupFontColor:=ColorBox12.Selected; InactiveTabFontColor:=ColorBox11.Selected; QuickAccessToolbarMoreColor:=ColorBox10.Selected; QuickAccessToolbarMoreBorderColor:=ColorBox9.Selected; end; Ribbon1.ColorMap:=Ribbon; end; end; […] end;
И теперь можем экспериментировать с цветовой схемой Ribbon сколько нашей душе угодно, подбирать свои цвета шрифтов и т.д. Например, я собрал вот такую «тошнотную» схемку:
Жуть, неправда ли? Но это проcто пример. А у нас остался ещё один открытый вопрос: как сменить не только цвет шрифта, но и тему оформления целиком? Ведь если просто прикинуть, сколько людей купили RAD Studio 2009-2010, сколько используют или пробуют использовать Ribbon Controls? И на всех всего 3 темы. Несерьёзно. Надо как-нибудь выделиться, создать что-то свое (на крайняк – купить за N зелёных енотов).
Благо разработчики из Embarcadero оставили нам возможность немного покреативить в свое удовольствие.
Судя по рисунку выше, креативщик из меня хреновенький, но я все-таки попробую. Первое, что следует сделать – понять каким образом и, самое главное, откуда беретя это красивое оформление панелей, менюшек и табов. Я решил оттолкнуться в своих поисках от модуля RibbonLunaStyleActnCtrls и поиски в итоге привели к следующему классу:
TCustomRibbonSkin = class public type TRibbonSkinLoadType = (ltResource, ltFile); private FBitmap: TAlphaBitmap; protected procedure DoLoadByResource; virtual; procedure DoLoadByFile; virtual; public constructor Create; virtual; destructor Destroy; override; function GetLoadType: TRibbonSkinLoadType; virtual; function GetResourceHandle: THandle; virtual; function GetLoadTypeValue: string; virtual; procedure LoadSkin; virtual; property Bitmap: TAlphaBitmap read FBitmap; end;
Получается с какого стиля оформления мы бы не начинали свои поиски – всё упрётся именно в этот класс. Как видите у этого класса не так уж и много свойств и методов.
С типом TribbonSkinLoadType всё вполне понятно – определяет откуда будет загружаться скрин: из ресурсного файла или же из файла на диске.
Далее одно единственное поле: FBitmap: TalphaBitmap – собственно это и есть файл с необходимыми изображениями для скина.
Следом идут два метода, которые срабатывают соответственно в зависимости от того откуда будет загружаться скин.
Но самое замечательное – это открытое для чтения свойство Bitmap. Помниться ещё когда у меня стояла Delphi 2009 я немог найти толком информации о расположении всех графических элементов в битмапе…надо было сразу искать здесь. Но это всё лирика. Давайте посмотрим как выглядит файл с элементами скина для Ribbon.
Возвращаемся к нашему приложению, бросаем на форму ещё одну кнопку, SaveDialog и пишем в свойстве Caption у кнопки «Сохранить скин», а в обработчике такой код:
[…] if SaveDialog1.Execute then Ribbon1.Style.RibbonSkin.Bitmap.SaveToFile(SaveDialog1.FileName); […]
Теперь мы можем воочую взглянуть на битмап скрина Ribbon и состряпать свой по образу и подобию. Файл весит не много ни мало 1056kb поэтому ради иллюстрации я приведу сжатый в gif и уменьшенный немного по размеру рисунок. Вот он:
Так как я не дизайнер и в PhotoShop практически ничего не соображаю, то ради эксперимнта я раскрасил немного некоторые области, дабы видеть что у меня получилось загрузить свой скин в программу. Теперь приступаем к фазе №2 – пишем свой модуль для загрузки скина.
Вы обращали внимание, что после первой же компиляции проекта с Ribbon в uses появляется как минимум один дополнительный модуль RibbonLunaStyleActnCtrls? Вот такой же самый модуль мы и будем писать.
Создаем пустой модуль и даем ему какое0нибудь громогласное название, например: RibbonMegaStyleActnCtrls. Сразу в uses подключаем три модуля: ActnMan, RibbonStyleActnCtrls и Ribbon. А также объявляем одну константу:
const LoadType: TCustomRibbonSkin.TRibbonSkinLoadType = ltFile;
То есть договариваемся, что самодельный скин будем грузить из bmp-файла. Теперь обявляем такой класс:
type TRibbonMegaStyleActionBars = class(TRibbonStyleActionBars) public function GetColorMapClass(ActionBar: TCustomActionBar): TCustomColorMapClass; override; function GetSkinClass: TCustomRibbonSkinClass; override; function GetStyleName: string; override; end;
и расписываем его методы:
implementation uses ActnMenus, SysUtils; function TRibbonMegaStyleActionBars.GetColorMapClass( ActionBar: TCustomActionBar): TCustomColorMapClass; begin Result := TRibbonLunaColorMap; end; function TRibbonMegaStyleActionBars.GetSkinClass: TCustomRibbonSkinClass; begin Result := TRibbonMegaSkin; end; function TRibbonMegaStyleActionBars.GetStyleName: string; begin Result := 'Ribbon - Mega'; // русскими буквами не писать! end;
Обратите внимание на первый метод – я использовал уже готовую цветовую схему от скина Luna, чтобы сильно не забивать пост лишними строками кода, Вы же можете определить в своем модуле собственную цветовую схему для скина, полагаю, что много времени это не займёт.
Теперь создаем класс для нашего скина, который будем использовать в программе:
TRibbonMegaSkin = class(TCustomRibbonSkin) public function GetLoadTypeValue: string; override; function GetLoadType: TCustomRibbonSkin.TRibbonSkinLoadType; override; end;
Методы опять же просты и неказисты (дли примера):
function TRibbonMegaSkin.GetLoadType: TCustomRibbonSkin.TRibbonSkinLoadType; begin Result := LoadType; //использовали нашу константу end;
function TRibbonMegaSkin.GetLoadTypeValue: string; begin Result := ExtractFilePath(ParamStr(0)) + 'mega.bmp'; //указали расположение файла end; end;
Если не устраивает то, что скин будет лежать прямо рядом с исполняемым файлом – нет проблем, укажите свой путь. А нам остается только зарегистрировать наш новый скин и вовремя его выгрузить. Не будем опять же изобретать велосипед (тем более, что на скорую руку он может получиться далеко не с круглыми колесами), а пишем тоже самое, что и для стандартных скинов в секциях initialization и finalization:
initialization RibbonMegaStyle := TRibbonMegaStyleActionBars.Create; RegisterActnBarStyle(RibbonMegaStyle); finalization UnregisterActnBarStyle(RibbonMegaStyle); RibbonMegaStyle.Free;
Да и незабудьте перед implementation объявить глобальную переменную:
var RibbonMegaStyle: TRibbonMegaStyleActionBars;
Теперь подключаем наш модуль в uses и в любом удобном для вас обработчике пишем:
[…] Ribbon1.Style:=RibbonMegaStyle; Ribbon1.Repaint; […]
Я добавил эти строки в обработчик кнопки для применения цветовой схемы. Вот какой вид приняла моя программа после того как я поиздевался над скином:
Жутко некрасиво, но зато ярко и сразу видно, что кто-то нарочно изуродовал Ribbon.
На сегодня всё. В качестве бонуса к посту прилагается та самая программка, которую я писал по ходу дела работы над статьей. В архиве с программой вы найдёте также её исходники, включая модули RibbonConsts (с одной переведенной строкой) и модулем тестового скина, который, в случае чего, избавит Вас от лишней писанины – просто поменяете путь и название файла и скин готов.
А вот и сам архив.
Низкий поклон автору и всех благ в наступающем старом новом году))) материал особенно ценен тем, что методом научного тыка до подобного недопетрить, а если не секрет, что служило первоисточником?
bambarmia Не секрет) Первоисточником послужил жутко нездоровый интерес и вопрос «Как это устроено?». А дальше, как я уже писал в статье — начал отслеживать все связи в модулях связанных с Ribbon. Т.к. раньше меня интересовала тема работы с интерфейсами, то особого страха перед тем, чтобы порыться в модулях и проверить некоторые моменты работы Ribbon не возникало. Ну и, конечно же, не обошлось без msdn. Хоть там сейчас вся инфа про Ribbon находится в .Net-технологиях, всё равно часть информации оказалась весьма ценной. Вот теперь думаю…есть 4 шага работы с Ribbon? Может стоит обобщить всю имеющуюся информацию и сделать большую большую статью?… Подробнее »
Здравствуйте, Vlad.
Скажите, пожалуйста, можно ли изменить высоту элементов в Application Menu?
На вскидку, не копаясь особо в устройстве меню, можно использовать CommandStyle для элемента меню csControl — тогда высота будет раза в три меньше, но элементы меню не будут выделяться (Action срабатывать будет).
Спасибо.
Хотелось бы, конечно, полноценные элеметы меню.
Ещё вопрос. Изменение ширины Application Menu.
А то добавляю длинные строки, а они не помещаются и ширина меню не увеличивается.
С шириной видимо придётся «по-колдовать», т.к. сходу решения не обнаружил. Сейчас работаю над объединением всех четырех статей про Ribbon Controls в один большой документ, думаю, что в процессе работы попробую рассмотреть Application Menu более подробно и рассказать об этом в блоге
Здравствуйте, Vlad. Респект за все 4 статьи! У меня вот два вопроса дурацких возникло.
Во-первых, как использовать класс RibbonMegaStyleActnCtrls :) в Си++?
И во-вторых, (у меня Win 7) ваши Delphi- приложения — с прозрачной строкой заголовка, а мои Builder-приложения — нет. Почему мир так жесток?
Про С++ точно не помогу ибо в этом языке я не соображаю вообще…обычно как-то всё было наоборот — С++ перегоняли под Дельфи :) И кстати, под C++ вроде бы Ribbon Controls на порядок мощнее проработаны самим Мелкомягким.
А про прозрачность разговор уже в одной из тем заходил (посмотрите комменты) — вроде бы основная проблема с прозрачностью — это неправильный или отсутствующий res-файл.
Спасибо, пороюсь… Ещё вопросик: какой параметр отвечает за цвет на изломе элемента меню и стрелочки справа, ведущей на sub-menu (в главном меню)?
А насчёт прозрачности — я нашёл только про изображения, что решается указанием у ImageList ColorDepth = cd32Bit. А я про строку заголовка в стиле Vista. Хотя мне это не так важно…
Отправьте мне на vlad383@mail.ru рисунок где видна ваша проблема, счас разберусь немного с авторизацией на сайте с помощью synapse и посмотрю, что там :)
А какие проблемы с авторизацией?
Да у меня никаких. Просто один из читателей попросил помочь с работай с Synapse, ещё вчера, а я в офф-лайн работу с головой ушел. вот теперь выстраиваю очередь, кому в какой последовательности отвечать…Попробую ответить всем
Спасибо за статьи я тут покряхтел и собрал воедино все 4 шага в Ворде 2010, куда их выложить?
Можешь их и отредактировать если что то не то
Буду очень благодарен, если пришлешь на vlad383@mail.ru я как раз собираю всё в одну кучу + добавляю кое-что новое
Отправил!!! отредактированый если сможешь отправь на мой ящик vitek_tlt@mail.ru
Ок. Как всё соберу — отправлю и тут пост напишу
Никак не могу заставить показываться Hints у элементов Aplication Menu.
Буду благодарен за помощь.
Hints всмысле стандартные подсказки или ScrinTips нужны?
для recent items — достаточно стандартных
для элементов слева — можно и ScreenTips
Хм..попробовал создать подсказку для элементов меню и не получилось. Хотя легко соорудил ScreenTip для самой кнопки меню. Что-то мне подсказывает, что ScreenTips внутри меню вообще не применяется. По поводу простых Hints разбираюсь…
Пытаюсь тут перенести скин Офиса 2010 в это дело. Если бы только не несколько проблем, то в принципе получается достаточно хорошо. Кнопочки, радиобоксы, сепараторы ещё не перенёс. Пока попробовал вкладки, фон и чекбоксы. Но если чекбоксы идеально наложились, то с фонами груб, страницы и вкладок возникли проблемы. Под активной вкладкой проявляется линии. Альфа каналы подправил, так что теоретически её быть не должно. А в начале групп появляется артефакт. Чем дальше группа — тем больше артефакт.
s005. radikal .ru/i212/1007/4e/ff774e03f8be.png
бипшка
slil .ru/29455498
есть какие-нибудь идеи как решить проблему?
У меня очень итересний вопрос!!!! Возможно ли както изменить стиль СТРОКИ СОСТОЯНИЯ как у ВОРД-а заокруглиными углами?
Можно, если сильно захотеть.
Привет, а не мог бы ты мне рассказать как примерно? заранее спасибо!!!!!
Или какие то статьи в кинуть!
В моем блоге статьи по PhotoShop не публикуются. Читай соответствующие темы — в сети их валом
На фотошопе я сам нарисую, мне интересно как обратиться к скину Строки состояния!!!!
открываешь Delphi.
Подключаешь в uses модуль RibbonStatusBar.
В любом месте программы пишешь
RibbonStatusBar.RoundCorner(5).
В папке C:\Program Files\CodeGear\RAD Studio\6.0\source\Win32\vcl нету такого файла
у меня 2009 год
Ну вот плохо, что нету. надо качать Delphi XE….
2010?
в 2010 тоже врядли будет…разработка-то новейшая…нужен Delphi XE
Delphi Prism 2011 с Visual Studio 2010?
тоже хорошие инструменты, но не Delphi XE
Я нашол тторент почти 2 гб, тебе кинуть торрент?
Да у меня лицензионная стоит
Инсталяха есть?
Конечно есть. И лицензия на год.
Я себе скачаю пиратку, у меня еще один вопрос, както я спрашивал как разширить меню главное, можно както?
А я уже отвечал — читай MSDN и лицензионное соглашение на использование Ribbon и прекрати извращать то, что извращать запрещено
[…] отличие от стилей для Ribbon Controls, VCL Styles имеют свой достаточно удобный редактор, […]
[…] webdelphi Продовжуємо порпатися в нетрях і хитросплетіннях Ribbon […]