Jak naprogramovat multibarevnou lištu pro jakékoliv rozlišení

Dnes jsem si dal trochu pauzu od toho předělávání starších Windows Forms programů na WPF, protože mě ukrutně nebavilo prodírat se kódy, o kterých jsem nevěděl proč jsem je kdysi tak naprogramoval a přemýšlel jsem jak trochu oživit ten svůj web.

Napadlo mě že bych mohl udělat barevnou lištu a tu vložit na každou stránku někde. Naprogramovat celé toto mi trvalo asi 4h.

Prvně co jsem udělal bylo že jsem si to promyslel a došel jsem k závěru, že by byla hloupost generovat lištu pro každou stránku zvlášť a proto jsem se rozhodl, že jednu barevnou lištu budou sdílet všechny rozlišení.

Pak jsem začal programovat. Začal jsem s třídou GeneralHelper. Nejtěžší bylo naprogramovat metodu CalculatePercentOfColorBars, která jednorázově při spuštění webu vypočte podle parametrů které jí předáte šířku v % pro jednotlivé barvy a samozřejmě se zde přiřadí každému divu unikátní barva. 🌈

U mě to sice může vypadat že to jsou stejné barvy na pohled, ale stačí si je dát pod kapátko a zjistíte že i když se liší třeba jen o „1“ tak se liší. A samozřejmě tu je ještě pole colorsColorBar, které obsahuje tolik barev, kolik maximálně zadáte jako druhý argument metodě.

Nezapomeňte, že každá barva tam může být jen jednou!

GeneralHelper.cs

C#
static string[] colorsColorBar = new string[] { "#3FB1F0",
    ...
};
/// <summary>
/// V klici bude rozliseni pro ktere se vztahuje, v hodnote pak pole s cisly, ktere budou vyjadrovat % z dostupne sirky ktere barva zabere
/// </summary>
public static Dictionary<short, byte[]> percentOfCountBars = new Dictionary<short, byte[]>();
/// <summary>
/// V klici bude rozliseni, v hodnote pak barvy ke poli, ktere je na stejnem klici jako zde barvy v slovniku percentOfCountBars
/// </summary>
public static Dictionary<short, List=""></short,><string>> colorsOfBars = new Dictionary<short, List=""></short,><string>>();
public static void CalculatePercentOfColorBars(short width, int count)
{
    List<string> finalColors = new List<string>(count);
    List<string> colors = new List<string>(colorsColorBar);
    byte percent = 100;
    byte usedPercent = 0;
    int lastIndex = count;
    lastIndex--;
    byte[] barWidths = new byte[count];
    byte i = 1;
    for (; i < 10; i++)
    {
        barWidths[i - 1] = i;
        int colorIndex = RandomHelper.RandomInt2(0, colors.Count);
        finalColors.Add(colors[colorIndex]);
        colors.RemoveAt(colorIndex);
        count--;
        usedPercent += i;
        percent -= i;
    }
    //
    while (percent > 0 && count != 0)
    {
        if (percent == 2)
        {
            break;
        }
        byte randomPercent = RandomHelper.RandomByte2(1, percent > 9 ? 9 : percent);
        if (randomPercent > percent)
        {
            continue;
        }
        barWidths[i - 1] = randomPercent;
        int colorIndex = RandomHelper.RandomInt2(0, colors.Count);
        finalColors.Add(colors[colorIndex]);
        colors.RemoveAt(colorIndex);
        count--;
        usedPercent += randomPercent;
        percent -= randomPercent;
        if (percent < 0)
        {
            break;
        }
        i++;
        if (percent < 10 && percent != 0)
        {
            for (int i2 = 1; i2 < percent + 1; i2++)
            {
                int index = i - 1;
                if (index > lastIndex)
                {
                    break;
                }
                barWidths[index] = 1;
                colorIndex = RandomHelper.RandomInt2(0, colors.Count);
                finalColors.Add(colors[colorIndex]);
                colors.RemoveAt(colorIndex);
                count--;
                if (count == 0)
                {
                    break;
                }
                usedPercent += 1;
                percent -= 1;
                if (percent < 0)
                {
                    break;
                }
                i++;
            }
        }
    }
    //-Zaverecna korekce
    if (usedPercent < 100)
    {
        i++;
        int remainder = 100 - usedPercent;
        if (barWidths.Length == i + 1)
        {
            barWidths[i] = (byte)remainder;
            int colorIndex = RandomHelper.RandomInt2(0, colors.Count);
            finalColors.Add(colors[colorIndex]);
        }
        else
        {
            barWidths[0] += (byte)remainder;
        }
    }
    int total = 0;
    for (int i3 = 0; i3 < barWidths.Length; i3++)
    {
        total += barWidths[i3];
    }
    if (total > 100)
    {
        int remainder = total - 100;
        barWidths[8] -= (byte)remainder;
    }
    byte[] trimmedValues = null;
    int trimmedLength = finalColors.Count;
    if (trimmedLength == barWidths.Length)
    {
        trimmedValues = barWidths;
    }
    else
    {
        trimmedValues = new byte[trimmedLength];
        for (int y = 0; y < trimmedLength; y++)
        {
            trimmedValues[y] = barWidths[y];
        }
    }
    trimmedValues = CA.JumbleUp<byte>(trimmedValues);
    percentOfCountBars.Add(width, trimmedValues);
    colorsOfBars.Add(width, finalColors);
}

Druhé místo kde musíte něco dopsat je Global.asax. Ten je vždy v rootu vašeho webového projektu – jen tam se bude správně spouštět při inicializaci startu vaší webové aplikace.

Global.asax (metoda Application_Start)

C#
GeneralHelper.CalculatePercentOfColorBars(800, 25);
GeneralHelper.CalculatePercentOfColorBars(840, 30);
//-short.MaxValue se bude pouzivat pokud chci umistit MultiColorLine na celou sirku stranky
GeneralHelper.CalculatePercentOfColorBars(short.MaxValue, 36);

Další místem kde musíte něco naprogramovat je třída MultiColorLine. Tato třída zodpovídá za vygenerování odpovídajícího HTML obsahu s barevnou lištou. Třídu HtmlGenerator vám tu dávat nebudu, odpovídající metody si zvládnete jistě naprogramovat sami:

MultiColorLine.cs

C#
using System.Collections.Generic;
public class MultiColorLine
{
    public static string GetHtml(short width)
    {
        byte[] widths = GeneralHelper.
        percentOfCountBars[width];
        List<string> colors = GeneralHelper.colorsOfBars[width];
        HtmlGenerator htmlGenerator = new HtmlGenerator();
        int bl = widths.Length - 1;
        for (int i = 0; i < bl; i++)
        {
            htmlGenerator.WriteTagWith2Attrs("div", "class", "partColorBar", "style", "width:" + widths[i] + "%;background-color:" + colors[i]);
            htmlGenerator.TerminateTag("div");
        }
        htmlGenerator.WriteTagWith2Attrs("div", "class", "partColorBar", "style", "width:" + widths[bl] + "%;background-color:" + colors[bl] + ";float:right;");
        htmlGenerator.TerminateTag("div");
        return htmlGenerator.ToString();
    }
}

Předposlední místo je pak samotná (Master)Page ve které zavoláte . Ve stránce na odpovídající místo vložte tento div a případně nastylujte podle vlastního uvážení:

Neco.Master

C#
<div id="divBarevnaLista" runat="server"></div>

Ve code-behindu pak dejte následující kód (pouze si upravte jak chcete mít lištu širokou v 1. argumentu), který vytvoří HTML kód a vloží vám jej jako vnitřek divu.

Neco.Master.cs

C#
divBarevnaLista.InnerHtml = MultiColorLine.GetHtml(800);

Ve stránce, případně externím CSS pak musíte mít i toto CSS:

Neco.css

CSS
.partColorBar {
    height: 5px;
    max-height: 5px;
    min-height: 5px;
    display: inline-block;
    padding: 0;
    margin: 0;
    float: left;
}

Posledním kódem který vám tu dám jsou ty další metody které jsem volal, abyste nemuseli tápat, jak je implementovat:

C#
internal static T[] JumbleUp<T>(T[] items)
{
    int bl = items.Length;
    for (int i = 0; i < bl; ++i)
    {
        int index1 = (RandomHelper.RandomInt() % bl);
        int index2 = (RandomHelper.RandomInt() % bl);
        T temp = items[index1];
        items[index1] = items[index2];
        items[index2] = temp;
    }
    return items;
}
public static class RandomHelper
{
    static Random random = new Random();
    internal static int RandomInt2(int min, int max)
    {
        return random.Next(min, max);
    }
    internal static byte RandomByte2(int min, int max)
    {
        return (byte)random.Next(min, max);
    }
}

Výsledek? 🥁


Default.aspx s barevnou listou


BibleServer s barevnou listou

Napsat komentář