Vektorski diamanti

Prejšnji vikend na //publish/ Hackathonu v Brežicah sem želel narediti igro, kjer sestavni del igre so diamanti. Kot mentor nisem imel veliko časa za izdelavo igre in sem raje izdelal fitnes aplikacijo Heart rate sensor for Zephyr HxM (že v WP trgovini). Preden sem šel na to aplikacijo, sem že naredil nekaj diamantov. Trenutno nimam časa za razvoj igre, če pa katerega zanimajo diamanti ali pa želi vedeti, kako enostavno narediti vektorske slike v XAML, je to pravi post.

image

XAML koda vseh likov je čisto spodaj.

Read the rest of this entry »

Navigacija za Windows 8.1 in Windows Phone 8.1 v MVVM

Pred kratkim sem spisal kodo za navigacijo med stranmi kar iz view modelov, prenašanje parametrov med stranmi, popolnoma ločen od UI-ja in na prenosljiv način. Kot za primer sem objavil izvirno kodo, ki jo lahko uporabite tudi v svojih lastnih projektih ali pa jo modificirate po želji. Pozneje bom mogoče napisal razlago, kako si lahko pišete svoj MVVM navigacijski sistem.

Koda je v celoti komentirana, zato bom tukaj napisal le korake, kako uporabiti knjižnico. Potrebovali boste Visual Studio 2013 Update 2. Windows Phone 8.0 trenutno ni podprt, ampak že delam tudi na tem.

Knjižnica Zenicy.NavigationUtility vsebuje vse kar potrebujete za MVVM navigacijo za Windows in Windows Phone 8.1 in je neodvisna od kakršne koli NuGet knjižnice. Če vas zanima implementacija, si poglejte WindowsNavigationService.

Namestitev:

Read the rest of this entry »

Pridobivanje informacij o Windows 8 napravi

Pridobivanje informacij o Windows 8 napravi je težje in bolj nepredvidljivo kot o Windows Phone 8 napravi (več v Pridobivanje informacij o Windows Phone napravi). Za večino informacij ne vemo, če so na voljo oz. kaj predstavljajo. Unikatni strojni ID se recimo lahko spremeni ob dodajanju ali odstranjevanju dodatnih naprav, nameščanje gonilnikov ali nameščanja orodij za virtualizacijo.

public static string GetHardwareUniqueID()
{
    var token = Windows.System.Profile.HardwareIdentification.GetPackageSpecificToken(null);
    IBuffer id = token.Id;
    byte[] bytes;

    using (var reader = DataReader.FromBuffer(id))
    {
        bytes = new byte[id.Length];
        reader.ReadBytes(bytes);
    }

    return BitConverter.ToString(bytes);
}

Priporočljiv način pridobivanja unikatnega ID-ja je generiranja GUID-a, vendar s to metodo na žalost ne morate zanesljivo ugotoviti ali je aplikacija že bila nameščena na to napravo. Ta ID tudi ni dostopen drugim aplikacijam.

public static string GetDeviceUniqueID()
{
    string key = "deviceID";
    var storage = ApplicationData.Current.LocalSettings.Values;
    if (storage.ContainsKey(key) && storage[key] is string)
    {
        return (string)storage[key];
    }

    string value = Guid.NewGuid().ToString();
    storage[key] = value;

    return value;
}

Z malo sprememb lahko dobite unikatni ID uporabnika. Namesto, da shranite GUID v lokalne nastavitve, jih shranite v roaming nastavitve. Ta podatek se prenaša med napravami, ampak uporabnik ima možnost odstraniti te podatke ob odstranjevanju aplikacije.

public static string GetUserUniqueID()
{
    string key = "userID";
    var storage = ApplicationData.Current.RoamingSettings.Values;
    if (storage.ContainsKey(key) && storage[key] is string)
    {
        return (string)storage[key];
    }

    string value = Guid.NewGuid().ToString();
    storage[key] = value;

    return value;
}

Zgornji dve kodi sta združljivi z Windows Phone 8 API-ji in jih lahko uporabite brez sprememb.

Za več informacij o napravi kot je npr. proizvajalec naprave, arhitektura procesorja in podobno, najdete tukaj:

http://attackpattern.com/2013/03/device-information-in-windows-8-store-apps/

Izdelava vektorskih slik za XAML razvijalce (1. del)

Včasih rabimo eno enostavno vektorsko sliko, ampak ne vemo od kod jo dobiti. Slike iz drugih virov ne moramo dovolj modificirati, da ustreza našim potrebam. Enostavne slike je mogoče sestaviti iz enostavnih oblik v XAML-u.

Prva ikona, ki jo bomo naredili, bo WiFi signal indikator. Ta je sestavljena iz 5 enako širokih štirikotnikov v obliki stopnic, ki jih ločujejo 4 prazni prostori. To ikono bomo naredili v dveh pristopih. V poznejših člankih bomo uporabljeno znanje izkoristili za bolj kompleksne primere.

Ikona iz enostavnih oblik

<StackPanel Orientation="Horizontal" VerticalAlignment="Top">
    <Rectangle Fill="White" VerticalAlignment="Bottom" Width="50" Height="50" Margin="0,0,20,0" />
    <Rectangle Fill="White" VerticalAlignment="Bottom" Width="50" Height="100" Margin="0,0,20,0" />
    <Rectangle Fill="White" VerticalAlignment="Bottom" Width="50" Height="150" Margin="0,0,20,0" />
    <Rectangle Fill="White" VerticalAlignment="Bottom" Width="50" Height="200" Margin="0,0,20,0" />
    <Rectangle Fill="White" VerticalAlignment="Bottom" Width="50" Height="250" Margin="0,0,20,0" />
</StackPanel>

image

Ta rešitev je omejena le na specifično velikost. S pomočjo Viewbox kontrole lahko izboljšamo prilagodljivost na velikost.

<Viewbox>
    <!— WiFi XAML koda –>
</Viewbox>

Ikona s pomočjo razdeljevanja Grid-a in pozicioniranja Rectangle-ov

Nekatere ikone pa so preveč kompleksne, da bi jih lahko hitro naredili le s nekaj oblikami. Večino ikon, ki so sestavljene iz kvadratov, lahko sestavimo s pomočjo razdeljevanja Grid kontrole v vrstice in stolpce in Rectangle kontrole. Postopek je dolgotrajnejši, je pa zato bolj fleksibilen in včasih bistveno bolj enostaven.

Verticalna porazdelitev

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
</Grid>

image

Tukaj imamo 5 vrstic s enako velikostjo ne glede na višino. Višina posamezne vrstice je 1/5 celotne višine grida.

Horizontal porazdelitev

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="2*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="2*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="2*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="2*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="2*" />
    </Grid.ColumnDefinitions>
</Grid>

image

Tukaj imamo 9 stolpcev, razdeljeno po 5 stolpcev s dvojno velikost in med njimi so stolpci s enojno velikost. To pomeni, da je vsak lihi stolpec 2x večji od sodega stolpca.

Pozicioniranje Rectangle-a

Znotraj tega grida lahko elementom določimo Grid.Row, Grid.Column, Grid.RowSpan in Grid.ColumnSpan, ki se uporabljajo za pozicioniranje elementa znotraj starša (Grid kontrola). Index za Row in Column se začne s 0 in Row/ColumnSpan morata biti vsaj 1.

<Rectangle Fill="White" Grid.Row="3" Grid.Column="2" Grid.RowSpan="2" />

image

Končni rezultat

Primer celotnega dizajna za Wifi signal indikator s pomočjo razdeljevanja vrstic in stolpcev znotraj Grid-a.

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="2*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="2*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="2*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="2*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="2*" />
    </Grid.ColumnDefinitions>

    <Rectangle Fill="White" Grid.Row="4" />
    <Rectangle Fill="White" Grid.Row="3" Grid.Column="2" Grid.RowSpan="2" />
    <Rectangle Fill="White" Grid.Row="2" Grid.Column="4" Grid.RowSpan="3" />
    <Rectangle Fill="White" Grid.Row="1" Grid.Column="6" Grid.RowSpan="4" />
    <Rectangle Fill="White" Grid.Column="8" Grid.RowSpan="5" />
</Grid>

image

Ta enostavna ikona načeloma ne potrebuje zadnje rešitve, saj nimamo veliko prednost pred prvim pristopom. V prihodnjem članku bo predstavljena malo bolj kompleksna ikona, kjer bo ta pristop bistveno lažji kot prvi pristop.