Копаемся в исходниках Windows 8 Metro Weather

После установки Windows 8 (64bit + VS2011) и ознакомления с новым интерфейсом Metro первым делом захотелось переключить температуру из градусов по фаренгейту в градусы по цельсию. Это подтолкнуло к копанию в исходниках, а затем и к русификации приложения.

О чем статья:
  • Где лежит и из чего состоит установленное приложение
  • Как переключить фаренгейты в цельсии
  • Как установленное приложение перенести в VS2011 и запустить в отладчике
  • Добавление кнопки в приложение
  • Частичная и полная русификация





Где лежит


Для тех кто не смотрел build или не обратил внимание, полный путь к папке с приложением: C:\Program Files\Applications\microsoft.weather_1.0.0.26_neutral_neutral_8wekyb3d8bbwe

Чтобы увидеть папку Applications нужно в проводнике открыть Program Files и на вкладке View поставить галочку Hidden items. Просто так попасть в папку Applications не получится, для этого понадобится добавить себе разрешения, для этого в свойствах этой папки идем на вкладку Security.
Приложение написано на javascript и состоит из набора файлов форматов .css, .html, .js, файла ресурсов .pri, сертификата подписи .p7x, и набора картинок и видеофайлов для фона

Переключаем фаренгейты в цельсии


Чтобы переключить фаренгейты в цельсии мне пришлось залезть в исходники. Тем кто еще не успел туда залезть для этого достаточно нажать Win + C выбрать пункт Settings и в появившейся панельке справа нажать Weather preferences и выбрать привычные цельсии.

Запускаем приложение в Visual Studio 2011


Чтобы это сделать мне понадобилось создать в VS пустой javascript проект. Затем взглянув на структуру проекта изменил название default.html на defaultHost.html, и перенес содержимое файла. Потом пришлось добавить в проект картинки, видео, таблицы стилей, js скрипты и скопировать содержимое AppxManifest.xml в package.appxmanifest. Чтобы из Metro не пропала “плитка” установленного приложения достаточно изменить в этом файле Package Name c Microsoft.Weather на другое.
В VS2010 добавить текстовые ресурсы можно было через меню в свойствах проекта, а здесь достаточно добавить в проект новый файл Resources File (.resjson). После добавления открываю файл и вижу закомментированое описание об использовании текстовых ресурсов. Вот вроде бы и все. Можно запускать приложение в Debug или Release, ставить точки останова и изучать как оно работает.

Добавим кнопку и подпишемся на клики


Взглянув на defaultHost.html решил поиграться с кодом и добавить свою кнопку с обработчиком события и своей картинкой.
Кнопку поставил на appbar, для этого скопировал код кнопки Remove City и вставил рядом. Вот что получилось:
<button id="ruCulture" class="win-command" ><br/>
                <span class="win-spritestates win-commandicon win-large ruicon"></span> <br/>
                <span id="cultureText" class="win-label" data-win-res="textContent: ruCulture">ru-RU</span><br/>
</button>

Теперь надо добавить обработчик нажатия, для этого в defaultNew.js нахожу добавление обработчика нажатия на Remove City и вставляю строчку кода:
id("ruCulture").addEventListener("click", switchCulture);

Функция id обёртка для document.getElementById, её можно найти в currentCityControl.js. switchCulture моя функция которая будет переключать язык локализации, об этом ниже в статье.

Частичная и полная русификация


Что значит частичная? Это значит просто смена локали на ru-RU в запросе к серверу погоды, и соответственно получение от сервера метеосводки на русском языке. Приложение остается на своем языке. А с добавлением текстовых ресурсов на русском языке получаем полную русификацию.

Для себя поставил задачу сделать кнопку переключения локали с ru-RU на fr-FR и сохранение этой настройки, чтобы после перезапуска приложение брало данные о погоде ня языке сохраненной локали.

В файле data.js есть строчка

var culture = R.getString("/webservice/culture");

где R из defaultHost.js R = new Windows.ApplicationModel.Resources.ResourceLoader();

В переменную culture заносится текущая локаль из файла ресурсов. Пишу функцию getCulture(), а эту строчку меняю на:
var culture = getCulture();


Затем иду в defaultHost.js и добавляю culture:

    WinJS.Namespace.define("Weather.Settings", {<br/>
        hourly: ApplicationData.current.localSettings.values["hourlydaily"] == "h",<br/>
        celsius: ApplicationData.current.localSettings.values["temp"] == "c",<br/>
        setForecastHourly: setForecastHourly,<br/>
        setForecastDaily: setForecastDaily,<br/>
        setUnitCelsius: setUnitCelsius,<br/>
        setUnitFahrenheit: setUnitFahrenheit,<br/>
        // Вот здесь добавляю<br/>
        culture: ApplicationData.current.localSettings.values["culture"]<br/>
    });<br/>
 <br/>
// После тут же сразу поставим локаль<br/>
Weather.Settings.culture = getCulture();


В конец defaultHost.js вставляю свои функции

function getCulture() {<br/>
if (!Weather.Settings.culture)<br/>
{<br/>
       // если уже есть сохраненная настройка загрузим иначе ru-RU <br/>
var idc = Windows.Storage.ApplicationData.current.localSettings.values["culture"];<br/>
if (idc) {<br/>
setCulture(idc);<br/>
} else {<br/>
setCulture("ru-RU");<br/>
}<br/>
}<br/>
return Weather.Settings.culture;<br/>
}<br/>
function setCulture(culture1) {<br/>
    if (Weather!==undefined) {<br/>
        Weather.Settings.culture = culture1;<br/>
        Windows.Storage.ApplicationData.current.localSettings.values["culture"] = culture1;<br/>
    }else {<br/>
            var idc = Windows.Storage.ApplicationData.current.localSettings.values["culture"];<br/>
            if (idc) {<br/>
                Weather.Settings.culture = idc;<br/>
            } else {<br/>
                Weather.Settings.culture = "ru-RU";<br/>
            }<br/>
    }<br/>
}


Для удобства отладки в defaultHost.html добавил div для вывода отладочной информации, а в defaultHost.js функцию deb(). Эту функцию можно вызвать из любого места скрипта и вывести любую информацию.

function deb(stok) {<br/>
var deb = document.getElementById("debugText");<br/>
if (deb) {<br/>
    deb.innerText = stok;<br/>
}<br/>
}


Осталось сделать переключение локали с сохранением настройки
Кнопка уже добавлена, нарисую для нее значек. В файле Weather_Commands_PNG_STRIP_40x.png хранятся все значки кнопок. Открываю файл и увеличиваю размер изображения вниз, рисую кнопки для разных состояний своей кнопки.
Чтобы значек кнопки отображался добавляю настройку стиля в defaultHost.css

 <br/>
button .ruicon<br/>
{<br/>
    background-position: 0px -280px;<br/>
}<br/>
 <br/>
button:active .ruicon<br/>
{<br/>
    background-position: -80px -280px;<br/>
}<br/>
 <br/>
button:disabled .ruicon<br/>
{<br/>
    background-position: -120px -280px;<br/>
}


Кнопка есть, значок на ней есть, на click по кнопке подписался осталось добавить функцию:
    function switchCulture(e) {<br/>
if (getCulture()=="ru-RU") {<br/>
     setCulture("fr-FR");<br/>
     } else {<br/>
     setCulture("ru-RU");<br/>
     }<br/>
        var culture = id("cultureText");<br/>
        if (Weather.Settings.culture) {<br/>
            culture.innerText = Weather.Settings.culture;<br/>
        }<br/>
        // TO-DO: <br/>
        // сразу перегрузим метеосводку на новом языке<br/>
        // попытка в лоб - не работает - не разобрался<br/>
        mainData.refresh(true).then(function () { });<br/>
        updateAllTiles();<br/>
    }


Запускаю приложение в Release, жму кнопку, ставится русская локаль. Останавливаю приложение, запускаю еще раз и приложение грузит погоду на родном языке. Грузит кстати с weather.service.msn.com

Полная русификация приложения через ресурсы


Прогноз уже на русском, осталось перевести интерфейс программы.
Metro приложение определяет локальные установки языка и в зависимости от этого загружает текстовые ресурсы. Добавляю в проект папку strings в нее файл resources.resjson и папку ru-RU с таким же файлом. Содержание файла:

{<br/>
"Add" : "Добавить",<br/>
"Pin" : "Закрепить",<br/>
"CurrentCitySearch" : "Поиск моего города",<br/>
"Tomorrow":"Завтра",<br/>
"Unpin":"Открепить",<br/>
"CurrentCityFound":"Мой город найден",<br/>
"Weather":"Погода",<br/>
"Description":"Погода",<br/>
"GatheringInfo":"Загружаю свежую метеосводку",<br/>
"PinCity":"PinCity",<br/>
"RemoveCity":"Удалить",<br/>
"CurrentCity":"Мой город",<br/>
"AddCity":"Добавить город",<br/>
"SummaryView":"По дням",<br/>
"Hourly":"По часам",<br/>
"EnterCity":"Введите город",<br/>
"AddCityError":"Ошибка добавления города",<br/>
"MaxCities":"Максимум городов",<br/>
"Preferences":"Настройки","Temperature":"Температура",<br/>
"Celsius":"Цельсий",<br/>
"Fahrenheit":"Фаренгейт",<br/>
"ruCulture":"Язык",<br/>
"debugText":"Отладка",<br/>
"LastUpdated" : "Обновлено <span id='lastUpdated'></span>.",<br/>
"Wind" : "Ветер",<br/>
"UVIndex" : "УФ индекс",<br/>
"Today" : "Сегодня",<br/>
"SplashScreenImage" : "Заставка",<br/>
"Search" : "Поиск",<br/>
"ResultsFor" : "Данные для",<br/>
"PercChanceOfRain" : "<span data-win-bind='innerText:precip'></span> возможность дождя",<br/>
"Low" : "Минимум",<br/>
"Humidity" : "Влажность",<br/>
"High" : "Максимум",<br/>
"FeelsLike" : "По ощущениям",<br/>
"CurrentCondition" : "Сейчас",<br/>
"ChanceOfRain" : "Возможен дождь",<br/>
"NetworkConnection" : "Не могу получить прогноз. Проверьте наличие интернета.",<br/>
"CannotRetrieveData" : "Не могу извлечь данные"<br/>
}


Запускаю приложение и Weather превращается в Погоду!
Поделиться публикацией
Ой, у вас баннер убежал!

Ну. И что?
Реклама
Комментарии 22
    +1
    С точки зрения рассмотрения исходников метро-приложения полезно, а вот перевод наверняка будет в версиях ближе к релизу.
    • НЛО прилетело и опубликовало эту надпись здесь
      +2
      Пробовали свои приложения писать? Как впечатления?
        +1
        Пока только изучаю среду и читаю msdn, возможно что-то и напишу, но скорее всего на c#. Впечатления отличные, хотя был момент когда Metro UI не адекватно реагировал — скролл бар таскаешь, а тайлы остаются на месте (причем информация на тайлах обновлялась нормально), так и не понял с чем это было связано.
        +1
        Цельсии-фаренгейты можно переключить и без копания в исходниках :) Там вроде правой кнопкой и куда-то тыкнуть, чтобы попасть в настройки.
          +1
          О том куда нажать написано в статье.
            0
            Приношу свои извинения.
          +1
          Спасибо, познавательно.
          А где скачать само приложение адаптированное для нас?
            +2
            Не нашел информацию не нарушит ли это лицензию. Так что пока не буду выкладывать готовое решение
              0
              Хм, чисто теоретически может нарушать, но в познавательных целях думаю можно, хотя решать вам.
            0
            Интересно, а рендер Metro UI будет только на базе движка IE, т.е. фактически монополизм? Или можно будет выбирать того кто более качественно отображает HTML?
              +1
              Думаю что и будет только ИЕ, как и в предыдущих версиях Windows. Все таки это нативный браузер вшитый в систему.
              Хотя может с помощью напильника и бубна можно будет переключить движок рендеринга html.
                +2
                Смотрел build онлайн, помню кто-то из докладчиков говорил, что сейчас разработчикам веб сайтов приходится затачивать сайты под каждый браузер, а с приложениями под Metro UI такого не будет. Из этого могу сделать вывод что будет на базе движка IE
                  0
                  IE далеко не эталон чтобы под него что-то затачивать. Поэтому для меня это как раз минус-фактор перехода на Win8. Т.е. проблемы IE будут теперь отрицательно сказываться на операционке в целом. Если сейчас я после установки Windows могу использовать любой альтернативный браузер, то сейчас меня вынуждают выбирать бразуер на уровне операционки. Хотя Win8 и здесь не первая. ChromeOS обогнал ее :)
                    0
                    Сейчас пишу из Win8, но не из IE. Скорее всего сторонние браузеры будут доработаны для запуска из Metro UI с пальцеориентированным интерфейсом и выводом на тайлы своей информации.
                      +2
                      Никто же не мешает использовать в качестве браузера ПО, отличное от IE10. Зато у Metro-приложений среда едина, что должно снизить сложность адаптации приложения под различные условия. По сути будет как с мобильными устройствами: что работает на одном айпаде, в 9 случаях из 10 работает и на другом. Ну и всегда остаётся возможность писать на C# или C++. ;)
                        +6
                        А какие проблемы будут у IE10 в момент выхода Windows 8, уточните, пожалуйста?
                    +7
                    Там же не только ХТМЛ5 и javascript, но и доступ к winRT.

                    И да ИЕ10 очень хорош. Попробуйте. Плюс к тому же аппартное ускорение очень хорошее.
                      0
                      Интересно когда магазин откроют, хочется уже что нибудь написать :)
                        0
                        Интересно, как это что-нибудь можно будет продавать, ведь исходники полностью открыты =\
                          0
                          не обязательно писать на JavaScript, можно и на С++
                          0
                          а Вы пишите, глядишь и магазин к релизу Вашего приложения откроют :)

                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                        Самое читаемое