четверг, 10 марта 2011 г.

Календарь с градиентной окраской

Скрипт написан с использованием скриптов londonali1010 и wlourf. Вывод календаря на текущий месяц с градиентной окраской.

Пример вывода календаря с использованием фона созданного скриптом backgraund.lua и окраской шрифта в два цвета


Календарь можно разворачивать под любым углом. Размер шрифта рассчитывается скриптом в зависимости от ширины календаря. В следующем примере показана раскраска календаря пятью цветами.

Скрипт календаря

--[[    calendar.lua by olgmen 10.03.2011
    За основу взят calendar by londonali1010 (2009)

x, y        -- координаты по горизонтали и вертикали, по умолчанию центр окна конки
calendar_width    -- ширина календаря, высота календаря расчитывается в зависимости от количества недель в месяце
rotate        -- поворот календаря на угол в градусах, по умолчанию 0
font_name    -- названия шрифта, по умолчанию "Ubuntu", размер шрифта вычисляется автоматически в зависимости от ширины календаря
italic        -- шрифт курсив, по умолчанию false - отключен
oblique        -- шрифт obliqueб по умолчанию false - отключен
bold        -- шрифт bold, по умолчанию false - отключен
colour        -- цвет текста, по умолчанию {{1, 0xffffff, 1}} - белый, без градации
orientation    -- направление градации цвета, по умолчанию "ww"

Для запуска необходимо дать скрипту права на исполнение и поместить в conkyrc следующие строки выше слова TEXT
  
    lua_load /путь_к_скрипту/calendar.lua
    lua_draw_hook_pre conky_draw_calendar
]]

require "cairo"
-- функция перекодировки цвета

function rgb_to_r_g_b2(tcolour)

    colour, alpha = tcolour[2], tcolour[3]

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

end


function conky_draw_calendar()

calendar_settings={

    {
    x = 150,
    y = 150,
    calendar_width = 200,
    rotate = 0,
    font_name = "KremlinCTT",
    bold = true,
    colour={{0, 0xffffff, 1},{1, 0xf00000, 1}},
    orientation = "nn"
    },

    }


    if conky_window == nil then return end
    if tonumber(conky_parse("$updates"))<3 then return end
     
    local cs = cairo_xlib_surface_create(conky_window.display, conky_window.drawable, conky_window.visual, conky_window.width, conky_window.height)

    for i,v in pairs(calendar_settings) do
        cr = cairo_create (cs)
        display_calendar(v)
            cairo_destroy(cr)
    end
  
    cairo_surface_destroy(cs)
end


function display_calendar(t)

    local function set_pattern()

-- задаём градиентную окраску

        if #t.colour == 1 then
            cairo_set_source_rgba(cr,rgb_to_r_g_b2(t.colour[1]))
        else
            local pat

            local pts=linear_orientation(t)
            pat = cairo_pattern_create_linear (pts[1],pts[2],pts[3],pts[4])
      
            for i = 1, #t.colour do
                cairo_pattern_add_color_stop_rgba (pat, t.colour[i][1], rgb_to_r_g_b2(t.colour[i]))
            end

            cairo_set_source (cr, pat)
        end
    end

-- проверка данных, установки по умолчанию

    if t.x            == nil then t.x = conky_window.width/2 end
    if t.y            == nil then t.y = conky_window.height/2 end
    if t.calendar_width    == nil then t.calendar_width = 150 end
    if t.rotate        == nil then t.rotate = 0 end
    if t.font_name        == nil then t.font_name = "Ubuntu" end
    if t.italic        == nil then t.italic = false end
    if t.oblique        == nil then t.oblique = false end
    if t.bold        == nil then t.bold = false end
    if t.colour        == nil then t.colour = {{1,0xffffff,1}} end
    if t.orientation    == nil then t.orientation = "ww" end

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

    local slant = CAIRO_FONT_SLANT_NORMAL
    local weight = CAIRO_FONT_WEIGHT_NORMAL

    if t.italic then slant = CAIRO_FONT_SLANT_ITALIC end
    if t.oblique then slant = CAIRO_FONT_SLANT_OBLIQUE end
    if t.bold then weight = CAIRO_FONT_WEIGHT_BOLD end
  
    cairo_select_font_face(cr, t.font_name, slant, weight)


-- проверяем правильность ввода цвета

    for i = 1, #t.colour do
        if #t.colour[i] ~= 3 then
            print ("error in color table")
            t.colour[i] = {1,0xFFFFFF,1}
        end
    end

-- берём данные о дате из системы

    local day = tonumber(os.date("%w"))
    local day_num = tonumber(os.date("%d"))

-- расчет календаря
    local remainder = day_num % 7

    start_day = day - (day_num % 7) + 1
    if start_day < 0 then start_day = 7 + start_day end
  
    month = tonumber(os.date("%m"))

-- вывод названия месяца на английском

--    month_name = os.date("%B")

-- вывод названия месяца на русском

    month_name = conky_parse("${time %B}")

    year = tonumber(os.date("%Y"))

    days = { "Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс" }

    function get_days_in_month()


        local month_days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
        local d = month_days[month]

-- вывод февраля в високосный год  
        if month == 2 and year % 4 == 0 and (year % 100 ~= 0 or year % 400 ~= 0)             then d = 29 end
      
        return d
    end

-- согласовываем координаты для вывода календаря

    cairo_translate(cr, t.x, t.y)

-- поворачиваем календарь

    cairo_rotate (cr,(math.pi/180)*t.rotate)
-- вычисляем размер шрифта относительно ширины календаря

    local dpi = tonumber(conky_parse('${exec xdpyinfo | grep resolution | cut -c 18-19}'))
    local font_pixel_size = t.calendar_width / 8
    local font_size = font_pixel_size * 72 / dpi

-- устанавливаем размер шрифта для месяца и года
    cairo_set_font_size(cr, font_size * 1.2)

    set_pattern ()

    local text = month_name .. " " .. year

    mx, my = 0, 0

    cairo_move_to(cr, mx - 3.5 * t.calendar_width / 8, my - 2.5 * t.calendar_width / 8)
    cairo_text_path(cr, text)

-- устанавливаем шрифт для вывода дней недели
    cairo_set_font_size(cr, font_size * 0.75)

    local xi, yi = mx - 3.5 * t.calendar_width / 8, my - 1.5 * t.calendar_width / 8

    for i = 1, 7 do
        cairo_move_to(cr, xi, yi)
        cairo_text_path(cr, days[i])
        xi = xi + t.calendar_width/8
    end

-- устанавливаем шрифт для чисел
    cairo_set_font_size(cr, font_size * 0.9)

    local xi = mx - 3.5 * t.calendar_width / 8 + (start_day - 1) * t.calendar_width / 8
    local yi = my - 0.5 * t.calendar_width / 8

    days_in_month = get_days_in_month()
  
    for i = 1, days_in_month do

-- выделяем сегодня

        if i == day_num then
            cairo_set_font_size(cr, font_size * 1.2)
        else
            cairo_set_font_size(cr, font_size * 0.9)
        end

        cairo_move_to(cr, xi, yi)
        cairo_text_path(cr, i)
        cairo_fill(cr)
        xi = xi + t.calendar_width / 8
        if xi == mx + t.calendar_width / 2 - t.calendar_width / 16 then
            xi = mx - 3.5 * t.calendar_width / 8
            yi = yi + t.calendar_width / 8

          
            if yi > my + t.calendar_width / 2 then
                yi = my - 0.5 * t.calendar_width / 8
            end
        end

    end

end

function linear_orientation(t)

    mx, my = -t.calendar_width/2, -t.calendar_width/2

    if t.orientation    == "nn" then
        p = {mx, my, mx, my + t.calendar_width}
    elseif t.orientation    == "ne" then
        p = {mx + t.calendar_width, my, mx, my + t.calendar_width}
    elseif t.orientation    == "ee" then
        p = {mx + t.calendar_width, my, mx, my}
    elseif t.orientation    == "se" then
        p = {mx +t.calendar_width, my + t.calendar_width, mx, my}
    elseif t.orientation    == "ss" then
        p = {mx, my + t.calendar_width, mx, my}
    elseif t.orientation    == "sw" then
        p = {mx, my + t.calendar_width, mx + t.calendar_width, my}
    elseif t.orientation    == "ww" then
        p = {mx, my, mx + t.calendar_width, my}
    else
        p = {mx, my, mx + t.calendar_width, my + t.calendar_width}
    end

    return p
end


Скачать скрипт можно здесь

Комментариев нет:

Отправить комментарий