Форум русскоязычного сообщества Ubuntu


Хотите сделать посильный вклад в развитие Ubuntu и русскоязычного сообщества?
Помогите нам с документацией!

Автор Тема: HOW-TO Создание приборов в conky  (Прочитано 3065 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн olgmen

  • Автор темы
  • Активист
  • *
  • Сообщений: 493
    • Просмотр профиля
HOW-TO Создание приборов в conky
« : 03 Января 2010, 17:56:12 »
Я не программист, так-что прошу извинить меня за некоторые непрофессиональные высказывания, пишу так, как сам понимаю, т.е. "кухонным языком". Если кто-нибудь из программистов отредактирует этот текст, буду очень рад.

В conky - 1.7.2, в репозитарии ubuntu-9.10 находится под именем conky-all, имеется возможность с помощью языков lua и cairo выводить в окно conky изображения геометрических фигур.

Для создания изображения необходимы некоторые команды на языке cairo. Все изображения выводятся по одной схеме.

Назначается точка начала вывода изображения, за начальную точку берется верхний левый угол.

cairo_move_to(cr, x, y)

Назначаем толщину выводимой линии s_th, значения от 1 - соответствует одному пикселю экрана, меньше единицы выводится неровная линия в виде пилы.

cairo_set_line_width(cr,s_th)

Назначаем цвет линии

cairo_set_source_rgba(cr, 0,0,0,1)

здесь первые три цифры цвет, по системе rgb, значения от 0 до 1, последняя цифра прозрачность цвета, значения от 0 до 1. Я редко использую такое назначение цвета из-за трудности подбора. О том как можно назначить цвет используя кодировку 0x00ff00 я опишу при объяснении написания скрипта.


Для вывода линии необходимо задать конечную точку

cairo_line_to(cr, x + 100, y)

будет выведена линия из точки x, y по горизонтали, слева направо, длиной 100 пикселей

cairo_line_to(cr, x, y + 100)

будет выведена линия из точки x, y , по вертикали, сверху вниз, длиной 100 пикселей.

Для рисования окружности необходимо задать длину радиуса, примем длину радиуса равной 100 пикселей

local radius = 100

Следующая команда задает значения для вывода в окно конки окружности с радиусом = radius с центром окружности в точке x, y начиная с 0 градусов и заканчивая в точке 360 градусов. Начало окружности находится на прямой горизонтальной линии проведенной из центра окружности, проще говоря с 90 градусов.

cairo_arc(cr, x, y, radius, 0, math.rad(360))

Следующая строка дает команду вывода изображения.

cairo_stroke(cr)

Для вывода прямоугольника необходимо задать ширину и высоту прямоугольника

local w = 100
local h = 50

Принцып вывода фигуры состоящей из прямых линий заключается в том, что первая линия выводится из заданой точки, вторая линия выводится из конечной точки первой и т.д.

Верхняя линия

cairo_line_to(cr, x + w, y)

Правая боковая линия

cairo_line_to(cr, x + w, y + h)

Нижняя линия

cairo_line_to(cr, x, y + h)

Левая боковая линия

cairo_line_to (cr, x, e)

Даем команду на вывод изображения

cairo_stroke(cr)

Для вывода изображения прямоугольника с закругленными углами необходимо задать радиус закругления

local r = 15

правда в этом случае при изменении размеров изображения радиус закругления остается неизменным, я использую следующий параметр радиуса закругления, который изменяется при изменении размеров.

local r = (w+h)/2*0.04

Привожу готовый образец

   cairo_move_to(cr, x + r, y)
   cairo_line_to(cr, x + w - r, y)
   cairo_arc(cr, x + w - r, y + r, r, -math.pi/2,0)
   cairo_line_to(cr, x + w, y + h - r)
   cairo_arc(cr, x + w - r, y + h - r, r, 0, math.pi/2)
   cairo_line_to(cr, x + r, y + h)
   cairo_arc(cr, x + r, y + h - r, r, math.pi/2, math.pi)
   cairo_line_to(cr, x, y + r)
   cairo_arc(cr, x + r, y + r, r, math.pi, math.pi*1.5)
   cairo_close_path(cr)

Команда cairo_close_path(cr) завершает рисунок, но не выводит изображение последней линии.

Это основные команды. Подробнее можно прочитать http://linfoline.homedns.org/tutorial_cairo/Cairo Tutorial.html

Теперь перейдем к написанию скрипта вывода изображения стрелочного прибора показывающего нагрузку CPU в процентах. Корпус прибора круглый. Начало шкалы 180 градусов конец шкалы 300 градусов. На шкалу выведем название в верхней части прибора.



Я использую gedit. Создаем пустой скрипт с расширением lua например: pribor.lua и помещаем его в домашнюю директорию, я все скрипты храню в папке ~/scripts

Все коментарии в скрипте начинаится с двух минусов -- и заканчиваются концом предложения. Если необходимо вывести коментарии состоящие из нескольких предложений, то в начале коментария ставится --[[ а в конце ]]

Любой скрипт с использованием языка cairo начинается со строки

require 'cairo'

-- Теперь необходимо назначить функции для работы скрипта

function cpu(cr, name, arg, max, x, y, s, bgc, bga, fgc, fga, prefix)

--[[   name   - название, может быть 'cpu', 'memperc', 'fs_used_perc', 'battery_used_perc'.
   arg   - аргумент, тот же, что и в conkyrc, т.е. 'cpu0', 'cpu1' и т.д.
   max   - максимальное выводимое значение, если значение выводим в %, то 100, для скорости интернета я расчитываю по формуле скорость/8 и округляю до большего значения, например у меня 6144/8=768 округляю до 1000, т.к. бывают броски превышающие скорость.
   x   - координаты по горизонтали верхнего левого угла изображения
   y   - координаты по вертикали верхнего левого угла изображения
   s   - диаметр прибора
   bgc   - цвет фона
   bga   - прозрачность фона
   fgc   - цвет линий
   fga   - прозрачность линий
   prefix   - наименование прибора
]]

-- функция перекодировки цвета из формата 0x000000 в формат 0,0,0,0

   function rgb_to_r_g_b(colour,alpha)
   return ((colour / 0x10000) % 0x100) / 255., ((colour / 0x100) % 0x100) / 255., (colour % 0x100) / 255., alpha
   end

-- задаем толщину выводимых линий

   local s_th = 2

-- забираем данные из ОС

   local i = 0
   local str=''
   local value=0
   str=string.format('${%s %s}', name, arg)
   str=conky_parse(str)
   value=tonumber(str)

-- рисуем круг радиусом s/2

   local radius = s/2
   cairo_set_line_width(cr,s_th)   
   cairo_arc(cr, x, y, radius, 0, math.rad(360))

-- назначаем цвет фона

   cairo_set_source_rgba(cr,rgb_to_r_g_b(bgc,bga))

-- закрашиваем циферблат

   cairo_fill_preserve(cr)

-- рисуем шкалу

-- назначаем цвет шкалы

   cairo_set_source_rgba(cr,rgb_to_r_g_b(fgc,fga))

-- сбрасываем счетчик
   
   local i = 0

-- деления выводим через 30 градусов

   local winkel = math.rad(30)

-- т.к. начало вывода окружностей и делений производится от отметки 90 градусов, сдвигаем начало шкалы на отметку 180 градусов, значение -4, выводим 11 делений.

      for i=-4,6,1 do
      cairo_move_to(cr, x - math.sin(winkel*i)*radius, y - math.cos(winkel*i)*radius)
      cairo_line_to(cr, x-math.sin(winkel*i)*(radius*0.8), y-math.cos(winkel*i)*(radius*0.8))
      end
      cairo_stroke(cr)

-- цветная шкала

      cairo_set_line_width(cr,s_th*2)         -- ширина шкалы
      cairo_arc(cr, x, y, radius, -4.7, -1.55)   -- зеленый сектор   
      cairo_set_source_rgba(cr, 0, 1, 0, 0.6)
      cairo_stroke(cr)
      cairo_arc(cr, x, y, radius, -1.55, -0.52)   -- желтый сектор
      cairo_set_source_rgba(cr, 1, 1, 0, 0.6)
      cairo_stroke(cr)
      cairo_arc(cr, x, y, radius, -0.51, 0.52)      -- красный сектор
      cairo_set_source_rgba(cr, 1, 0, 0, 0.4)
      cairo_stroke(cr)

-- для того, чтобы текст находился под изображением стрелки, выводим текст

-- параметры выводимого шрифта, подбирал экперементально, т.е. методом втыка

      local wa = s/5
      local ha = s/10
      local ra = (wa+ha)/2*0.04

-- назначаем размер шрифта

      cairo_set_font_size(cr, ha*(15/11))

-- назначаем точку вывода шрифта

      cairo_move_to(cr, x - wa, y - ha)

-- назначаем белый цвет для шрифта

      cairo_set_source_rgba(cr, 1, 1, 1, 1)

-- выводим шрифт

      cairo_show_text(cr, prefix)

-- вывод стрелки

-- назначаем длину стрелки

      local length = s/2*0.65

-- назначаем толщину стрелки

      cairo_set_line_width(cr,s_th)

-- точка вывода стрелок

      cairo_move_to(cr, x, y)

-- рисуем стрелки. Здесь ((value/max)*300)) max - максимальное значение, 300 - максимальный угол отклонения стрелки

      cairo_line_to(cr, x - math.sin(math.rad((value/max)*300))*length, y + math.cos(math.rad((value/max)*300))*length)

      cairo_stroke(cr)
end

--[[ скрипт вывода прибора практически готов, переходим к заключительной части. Для работы скрипта необходимы следующие строки ]]

function conky_widgets()
   if conky_window == nil then return end
   local cs = cairo_xlib_surface_create(conky_window.display, conky_window.drawable, conky_window.visual, conky_window.width, conky_window.height)

--[[ эти строки запускают скрипт, следующие строки задают данные для выполнения скрипта. ]]

--[[ CPU0 ]]
   cr = cairo_create(cs)
   cpu(cr, 'cpu', 'cpu0', 100, 100, 120, 100, 0x151515, 1, 0xc0c0c0, 1, "CPU0")

--[[   name   - название, может быть 'cpu', 'memperc', 'fs_used_perc', 'battery_used_perc'.
   arg   - аргумент, тот же, что и в conkyrc, т.е. 'cpu0', 'cpu1' и т.д.
   max   - максимальное выводимое значение, если значение выводим в %, то 100, для скорости интернета я расчитываю по формуле скорость/8 и округляю до большего значения, например у меня 6144/8=768 округляю до 1000, т.к. бывают броски превышающие скорость.
   x   - координаты по горизонтали верхнего левого угла изображения
   y   - координаты по вертикали верхнего левого угла изображения
   s   - диаметр прибора
   bgc   - цвет фона
   bga   - прозрачность фона
   fgc   - цвет линий
   fga   - прозрачность линий
   prefix   - наименование прибора
]]
   cairo_destroy(cr)

--[[ на это место можно скопировать строки
      
      cr = cairo_create(cs)
      cpu(cr, 'cpu', 'cpu0', 100, 100, 120, 100, 0x151515, 1, 0xc0c0c0, 1, "CPU0")
      cairo_destroy(cr)

и заменив 'cpu0' на 'cpu1', а также координаты, вывести второе ядро.
]]

end


Для запуска скрипта в .conkyrc выше TEXT вписываем следующие строки

lua_load ~/путь_к_скрипту/название_скрипта.lua
lua_draw_hook_pre widgets
TEXT

Если ниже TEXT ничего не написано, то conky не запустится, поэтому пишем строку

${voffset 50}

Если изображение будет обрезано по нижней кромке, просто увеличте значение до 100 или более.

Готовый скрипт

(Нажмите, чтобы показать/скрыть)

кто хочет, тот добьется,
кто ищет, тот всегда найдет

 

Страница сгенерирована за 0.035 секунд. Запросов: 25.