WelcomePage.xaml.cpp 4.66 KB
Newer Older
Nicolas Jager's avatar
Nicolas Jager committed
1 2 3
/**************************************************************************
* Copyright (C) 2016 by Savoir-faire Linux                                *
* Author: Jger Nicolas <nicolas.jager@savoirfairelinux.com>              *
4
* Author: Traczyk Andreas <andreas.traczyk@savoirfairelinux.com>          *
Nicolas Jager's avatar
Nicolas Jager committed
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
*                                                                         *
* This program is free software; you can redistribute it and/or modify    *
* it under the terms of the GNU General Public License as published by    *
* the Free Software Foundation; either version 3 of the License, or       *
* (at your option) any later version.                                     *
*                                                                         *
* This program is distributed in the hope that it will be useful,         *
* but WITHOUT ANY WARRANTY; without even the implied warranty of          *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
* GNU General Public License for more details.                            *
*                                                                         *
* You should have received a copy of the GNU General Public License       *
* along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
**************************************************************************/
#include "pch.h"

#include "WelcomePage.xaml.h"
atraczyk's avatar
atraczyk committed
22
#include "AboutPage.xaml.h"
Nicolas Jager's avatar
Nicolas Jager committed
23

24 25 26
#include "qrencode.h"
#include <MemoryBuffer.h>   // IMemoryBufferByteAccess

Nicolas Jager's avatar
Nicolas Jager committed
27 28
using namespace RingClientUWP;
using namespace RingClientUWP::Views;
29
using namespace RingClientUWP::ViewModel;
Nicolas Jager's avatar
Nicolas Jager committed
30

atraczyk's avatar
atraczyk committed
31 32 33
using namespace Windows::UI::ViewManagement;
using namespace Windows::UI::Core;
using namespace Windows::UI::Xaml::Controls;
34 35 36
using namespace Windows::Storage;
using namespace Windows::UI::Xaml::Media::Imaging;
using namespace Windows::Graphics::Imaging;
atraczyk's avatar
atraczyk committed
37

Nicolas Jager's avatar
Nicolas Jager committed
38 39 40
WelcomePage::WelcomePage()
{
    InitializeComponent();
41 42

    RingD::instance->shareRequested += ref new ShareRequested(this, &WelcomePage::generateShareData);
43 44 45
};

void
46
WelcomePage::_welcomeAboutButton__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
47
{
48 49
    auto rootFrame = dynamic_cast<Windows::UI::Xaml::Controls::Frame^>(Window::Current->Content);
    rootFrame->Navigate(Windows::UI::Xaml::Interop::TypeName(Views::AboutPage::typeid));
50 51 52
}

void
53
WelcomePage::generateShareData()
54
{
55 56
    auto ringId = AccountListItemsViewModel::instance->_selectedItem->_account->ringID_;
    auto ringId2 = Utils::toString(ringId);
atraczyk's avatar
atraczyk committed
57

58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
    _ringId_->Text = ringId;
    _welcomeAboutButton_->Margin = Windows::UI::Xaml::Thickness(0.0, 24.0, 0.0, 0.0);

    auto qrcode = QRcode_encodeString(ringId2.c_str(),
        0, //Let the version be decided by libqrencode
        QR_ECLEVEL_L, // Lowest level of error correction
        QR_MODE_8, // 8-bit data mode
        1);

    if (!qrcode) {
        WNG_("Failed to generate QR code: ");
        return;
    }

    const int STRETCH_FACTOR = 4;
    const int widthQrCode = qrcode->width;
    const int widthBitmap = STRETCH_FACTOR * widthQrCode;

    unsigned char* qrdata = qrcode->data;

    auto frame = ref new SoftwareBitmap(BitmapPixelFormat::Bgra8, widthBitmap, widthBitmap, BitmapAlphaMode::Premultiplied);

    const int BYTES_PER_PIXEL = 4;


    BitmapBuffer^ buffer = frame->LockBuffer(BitmapBufferAccessMode::ReadWrite);
    IMemoryBufferReference^ reference = buffer->CreateReference();

    Microsoft::WRL::ComPtr<IMemoryBufferByteAccess> byteAccess;
    if (SUCCEEDED(reinterpret_cast<IUnknown*>(reference)->QueryInterface(IID_PPV_ARGS(&byteAccess))))
atraczyk's avatar
atraczyk committed
88
    {
89 90 91
        byte* data;
        unsigned capacity;
        byteAccess->GetBuffer(&data, &capacity);
atraczyk's avatar
atraczyk committed
92

93
        auto desc = buffer->GetPlaneDescription(0);
atraczyk's avatar
atraczyk committed
94

95 96
        unsigned char* row, *p;
        p = qrcode->data;
atraczyk's avatar
atraczyk committed
97

98 99 100 101
        for (int u = 0; u < widthBitmap; u++) {
            for (int v = 0; v < widthBitmap; v++) {
                int x = static_cast<int>((float)u / (float)widthBitmap * (float)widthQrCode);
                int y = static_cast<int>((float)v / (float)widthBitmap * (float)widthQrCode);
atraczyk's avatar
atraczyk committed
102

103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
                auto currPixelRow = desc.StartIndex + desc.Stride * u + BYTES_PER_PIXEL * v;
                row = (p + (y * widthQrCode));

                if (*(row + x) & 0x1) {
                    data[currPixelRow + 3] = 255;
                }
            }
        }

    }
    delete reference;
    delete buffer;

    auto sbSource = ref new Media::Imaging::SoftwareBitmapSource();

    sbSource->SetBitmapAsync(frame);

    _selectedAccountQrCode_->Source = sbSource;
    _selectedAccountQrCode_->Visibility = VIS::Visible;
}