SlideShare a Scribd company logo
1 of 41
Download to read offline
Lovely Gray Buttons
free/libre history of widgets
with code snippets inside

Очаровательные серые кнопки
свободная история виджетов
с фрагментами кода
1983 - Apple Lisa Workshop
●

Разрабатывать софт для Apple Lisa
предполагалось в отдельной ОС с
полноэкранной консолью и единственным GUIприложением - текстовым редактором...
–

●

...писать код, компилировать, а потом
перезагружаться :)

Софт писался на Паскале, но требовал от
программиста глубоких знаний архитектуры ОС
–

упрощенный фреймворк виджетов должен был
называться Lisa ToolKit, но как раз к его выпуску
платформу Lisa закрыли
Среда разработки была
консольной, а из GUIинструментов имела
лишь текстовый редактор
1982 - Andrew Project :)
●

Сетевая компьютерная среда университета
Карнеги-Меллон включала Andrew User
Interface System (AUIS)
–

Andrew User Environment
(AUE) — редактор, справка,
весь GUI

–

Andrew Toolkit (ATK) —
коллекция встраиваемых
и форматируемых объектов

–

The Andrew Message System
(AMS) — почта и BBS-софт
Andrew toolkit in it's best :)
1988 ­ Project Athena (XAW)
●

●

Проект
MTI, DEC и IBM
по разработке
распределенной
вычислительной
среды кампуса
● привел к
созданию X
Window System,
Kerberos,
Zephyr...
Впервые словом
"виджеты"
обозначены
элементы
управления
XAW helloworld and widget set
#include <stdlib.h>
#include <X11/StringDefs.h>
#include <X11/Intrinsic.h> 
#include <X11/Xaw/Command.h> 
void quit(Widget w, XtPointer client, 
XtPointer call){
   exit(0); 
}
main(int argc, char **argv) {
    Widget toplevel;
    Widget command;
    toplevel = XtInitialize(argv[0],
"hello_world",NULL, 0, &argc, argv);
    command = XtCreateManagedWidget(
"hello!", commandWidgetClass, toplevel,
NULL, 0);
    XtAddCallback(command,XtNcallback,
quit, NULL);
    XtRealizeWidget(toplevel);
    XtMainLoop();
}
1988 ­ OPEN LOOK и XView
Совместные усилия 
Sun, AT&T и Xerox по 
созданию 
стандартизированного 
Unix­GUI
•Овальные кнопки и 
треугольнички, "чтоб 
Apple не мог засудить"
•

Реализация Open Look для X Window System
называлась XView
•Sun выложила код в свободный доступ в
начале 1090-х, сделав XView первым
свободным тулкитом
•
1988 ­ Motif
Создан DEC и Hewlett­Packard как 
альтернатива OPEN LOOK
•Изначально требовал от разработчиков 
лицензионных отчислений
•Около 2000 года создан LGPL­клон Lesstiff 
(заброшен в 2009)
•В 2000 появилась и freeware­версия Open Motif, 
а с 2012 Motif под LGPL
•

•
Motif widgets
& helloworld
#include <Xm/XmAll.h>
void main(int argc, char *argv[]) {
Widget toplevel, main_w, button;
XtAppContext app;
XtSetLanguageProc(NULL, NULL, NULL);
toplevel = XtVaAppInitialize(&app, "main",
NULL, 0, &argc, argv, NULL, NULL);
main_w =
XtVaCreateManagedWidget("main_w",
xmMainWindowWidgetClass, toplevel,
XmNscrollingPolicy, XmAUTOMATIC, NULL);
button = XtVaCreateWidget("Hello World",
xmLabelWidgetClass, main_w, NULL);
XtManageChild(button);
XtRealizeWidget(toplevel);
XtAppMainLoop(app);
}
1985 - WinAPI
●

Тулкит, задуманный как запредельно гибкий в
программировании
–

–

●

Программист может взаимодействовать со всей внутренней
архитектурой...
...и из-за этого вынужден самостоятельно выполнять массу
низкоуровневых операций

Windows 1.0 SDK содержал самый скандальный
helloworld в истории GUI...
–

...cостоявший из hello.c (150 строк) и hello.rc (20 строк)

–

при том, что весь WinAPI в тот момент включал 450
системных вызовов :)
/* Hello.c
Hello Application
Windows Toolkit Version 1.03
Copyright (c) Microsoft
1985,1986
*/
#include "windows.h"
#include "hello.h"
char szAppName[10];
char szAbout[10];
char szMessage[15];
int MessageLength;
static HANDLE hInst;
FARPROC lpprocAbout;
long FAR PASCAL
HelloWndProc(HWND, unsigned,
WORD, LONG);
BOOL FAR PASCAL About( hDlg,
message, wParam, lParam )
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;

/* Procedure called when the application is
loaded for the first time */
BOOL HelloInit( hInstance )
HANDLE hInstance;
{
PWNDCLASS pHelloClass;
/* Load strings from resource */
LoadString( hInstance, IDSNAME,
(LPSTR)szAppName, 10 );
LoadString( hInstance, IDSABOUT,
(LPSTR)szAbout, 10 );
MessageLength = LoadString( hInstance,
IDSTITLE, (LPSTR)szMessage, 15 );
pHelloClass =
(PWNDCLASS)LocalAlloc( LPTR,
sizeof(WNDCLASS) );
pHelloClass->hCursor
=
LoadCursor( NULL, IDC_ARROW );
pHelloClass->hIcon
=
LoadIcon( hInstance,
MAKEINTRESOURCE(HELLOICON) );
int PASCAL WinMain( hInstance, hPrevInstance,
lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
MSG msg;
HWND hWnd;
HMENU hMenu;
if (!hPrevInstance) {
/* Call initialization procedure if this is the first
instance */
if (!HelloInit( hInstance ))
return FALSE;
}
else {
/* Copy data from previous instance */
GetInstanceData( hPrevInstance,
(PSTR)szAppName, 10 );
GetInstanceData( hPrevInstance, (PSTR)szAbout,
10 );
GetInstanceData( hPrevInstance,
(PSTR)szMessage, 15 );
GetInstanceData( hPrevInstance,
/* Insert "About..." into system menu */
hMenu = GetSystemMenu(hWnd, FALSE);
ChangeMenu(hMenu, 0, NULL, 999, MF_APPEND |
MF_SEPARATOR);
ChangeMenu(hMenu, 0, (LPSTR)szAbout,
IDSABOUT, MF_APPEND | MF_STRING);

case WM_DESTROY:
PostQuitMessage( 0
/* Make window visible according to the way the app is
);
activated */
break;
ShowWindow( hWnd, cmdShow );
UpdateWindow( hWnd );
case WM_PAINT:
BeginPaint( hWnd,
/* Polling messages from event queue */
while (GetMessage((LPMSG)&msg, NULL, 0, 0)) { (LPPAINTSTRUCT)&ps );
HelloPaint( ps.hdc );
TranslateMessage((LPMSG)&msg);
EndPaint( hWnd,
DispatchMessage((LPMSG)&msg);
(LPPAINTSTRUCT)&ps );
}
break;
return (int)msg.wParam;
default:
}
return
DefWindowProc( hWnd,
message, wParam,
/* Procedures which make up the window class. */
long FAR PASCAL HelloWndProc( hWnd, message, lParam );
1987 - NextSTEP
●

●

API на
основе
Objective C
Нативная
поддержка
интроспекции
объектов и
первая
RADсистема
GNUStep helloworld
#include "AppController.h"
#include <AppKit/AppKit.h>
int main(int argc, const char *argv[]) `{
NSAutoreleasePool *pool;
AppController *delegate;
pool = [[NSAutoreleasePool alloc] init];

#include <AppKit/AppKit.h>

- (void) applicationWillFinishLaunching: (NSNotification *) not
{
/* Create Menu */
NSMenu *menu;
NSMenu *info;
menu = [NSMenu new];

[NSApp setDelegate: delegate];

[menu addItemWithTitle: @"Info"

return NSApplicationMain (argc, argv);
}

/* Create Window */
window = [[NSWindow alloc]
initWithContentRect: NSMakeRect(300, 300,
200, 100)
(NSTitledWindowMask |

NSMiniaturizableWindowMask |
NSResizableWindowMask)
NSBackingStoreBuffered

[menu addItemWithTitle: @"Hide"

[window setTitle: @"Hello World"];

keyEquivalent: @"h"];

#define _AppController_H_
#include <Foundation/NSObject.h>
@class NSWindow;
@class NSTextField;
@class NSNotification;

action: @selector(terminate:)

NSWindow *window;
NSTextField *label;
}

/* Create Label */
label = [[NSTextField alloc] initWithFrame:
NSMakeRect(30, 30, 80, 30)];
[label setSelectable: NO];

keyEquivalent: @"q"];

[label setBezeled: NO];
info = [NSMenu new];

[label setDrawsBackground: NO];

[info addItemWithTitle: @"Info Panel..."

[label setStringValue: @"Hello World"];

action: @selector(orderFrontStandardInfoPanel:)

[[window contentView] addSubview: label];

keyEquivalent: @""];
[info addItemWithTitle: @"Preferences"
action: NULL

@interface AppController : NSObject {

keyEquivalent: @""];

RELEASE(label);
}
- (void) applicationDidFinishLaunching:
(NSNotification *) not {
[window makeKeyAndOrderFront: self];

[info addItemWithTitle: @"Help"
action: @selector (orderFrontHelpPanel:)
keyEquivalent: @"?"];

}
- (void) dealloc {
RELEASE(window);

- (void)applicationWillFinishLaunching:(NSNotification *) not;
- (void)applicationDidFinishLaunching:(NSNotification *) not;

[menu setSubmenu: info
forItem: [menu itemWithTitle:@"Info"]];

@end
#endif /* _AppController_H_ */

backing:
defer: YES];

action: @selector(hide:)
[menu addItemWithTitle: @"Quit"

#ifndef _AppController_H_

styleMask:

action: NULL
keyEquivalent: @""];

RELEASE(pool);

RELEASE(menu);

@implementation AppController

delegate = [[AppController alloc] init];
[NSApplication sharedApplication];

[NSApp setMainMenu:menu];

[super dealloc];
}

RELEASE(info);

@end
1990 - AmigaOS 2.0
●

Базовая библиотека GUI Intuition
расширена тулкитом
стандартных виджетов
gadtools.library и объектноориентированным API BOOPSI
–

●

Основыми проблемами GUI
остаются бедный запас виджетов,
фиксированные размеры шрифтов
и окон

В 1992 появляется сторонний
тулкит MUI, умеющий
кастомизировать виджеты
–

Свободный клон MUI под
названием Zune входит в состав
AROS (свободного клона
AmigaOS)

#include <libraries/mui.h>
#include <proto/muimaster.h>
// Sample application:
ApplicationObject,
SubWindow, WindowObject,
WindowContents, VGroup,
Child, TextObject, MUIA_Text_Contents,
"Hello World!", End,
End,
End,
End;
199x — от Win16 к Win32
Тулкиты-обёртки
Большинство тулкитов-оберток
появляется под Windows. Цели их
создания:
●

●

●

Обёртки стандартных виджетов:
●

MFC (C++)

Упрощение исходного кода

●

AWT (Java)

Упраление размещением
элементов

●

wxWidgets (C++)

●

...

Обработкой событий,
многопоточность и др.

Альтернативные тулкиты:

Легкая отладка и упрощение кода

●

●

Qt (C++, кастомизируемый)

●

Многоплатформенность

●

GTK+ (C, кастомизируемый)

●

FOX (C++, Win95-sytle)...

–

Некоторые задуманы как способ
сделать программу, которую можно
собрать под любую из мэйнстримных
ОС

●

FLTK (C++/embedded,
кастомизируемый на 3-4 темы)
Обертки или альтернативные
виджеты?
1991 — Tcl/Tk
●

●

●

Tk родился в университете Беркли как
реакция на слишком сложную разработу
интерфейсов с Motif, и был задуман
предельно простым в программировани
Реализован как одно из расширений
скриптового языка Tcl
Tcl/Tk был довольно быстро портирован на
другие платформы, и до 1997 года пугал их
пользователей визуальным стилем Motif
#!/usr/bin/wish
button .hello -text "Hello, World!" -command { exit }
pack .hello
1992 - MFC

#include <afxwin.h>
#define IDC_BUTTON 100
class CButtonApp : public CWinApp {
public:
virtual BOOL InitInstance();
};

●

●

●

Первая и наиболее
успешная обертка к
WinAPI
C++ во всей красе:
наследование от
класса окна и т.д.
События связываются
с обработчиками с
помощью макросов

CButtonApp ButtonApp;
class CButtonWindow : public CFrameWnd {
CButton *button;
public:
CButtonWindow();
afx_msg void HandleButton();
DECLARE_MESSAGE_MAP()
};
void CButtonWindow::HandleButton() {
MessageBox("Hello World", "Hello!", MB_ICONEXCLAMATION );
}
BEGIN_MESSAGE_MAP(CButtonWindow, CFrameWnd)
ON_BN_CLICKED(IDC_BUTTON, HandleButton)
END_MESSAGE_MAP()
BOOL CButtonApp::InitInstance() {
m_pMainWnd = new CButtonWindow();
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
CButtonWindow::CButtonWindow() {
CRect r;
Create(NULL, "CButton Tests", WS_OVERLAPPEDWINDOW,
CRect(0,0,200,200));
GetClientRect(&r);
r.InflateRect(-20,-20);
button = new CButton();
button->Create("Push me", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, r, this,
IDC_BUTTON);
}
1993 ­ победа CDE
Окружение рабочего стола CDE и тулкит Motiff 
побеждают в битве за стандарт Unix­десктопа
•спецификация OPEN LOOK уходит в забвение, 
Sun сворачивает основанное на ней окружение 
рабочего стола OpenWindows в пользу CDE
•
1995 — Java AWT
●

●

●

●

Кроссплатформенная Java-обёртка над нативными
виджетами
Для полной нативности Sun Microsystems
решительно отказывалась включать в набор
виджеты, остутствующие в какой-либо из платформ
Зато пользователи получили автоматическое
размещение компонент с помощью шести layout
managers (аналог geometry managers из Tk)
Обработчики событий реализуются
переопределением функций из интерфейсов
(упрощенный аналог множественного наследования)
1995 - Qt
#include <qapplication.h>
●

●

●

C++ с предкомпиляцией
специальным
кодогенератором (moc),
обрабатывающим
дополнительные Qtабстракции
семь менеджеров
размещения виджетов
Абстракции слот и
сигнал для обработки
событий

#include <qmainwindow.h>
#include <qpushbutton.h>
#include <qfont.h>
int main(int argc, char **argv) {
QApplication myApp(argc, argv);
QMainWindow* myWin = new QMainWindow(0, 0, 0);
myWin->resize(500, 300);
myWin->move(200, 100);
QPushButton* quitButton = new QPushButton("Quit",
myWin);
quitButton->resize(60, 30);
quitButton->move(220, 135);
quitButton->setFont(QFont("Times", 18, QFont::Bold));
QObject::connect(quitButton, SIGNAL(clicked()), &myApp,
SLOT(quit()));
myApp.setMainWidget(myWin);
myWin->show();
return myApp.exec();
}
1997 — GTK (сначала без +)
●

●

●
●

Изначально создавался
как замена Motif в GIMP
0.60
К версии GIMP 0.99
тулкит переписали,
добавили ООП и плюсик в
названии

#include <gtk/gtk.h>
int main (int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *label;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window),
"Hello, world!");
g_signal_connect(window, "destroy",
G_CALLBACK(gtk_main_quit), NULL);

3 менеджера размещения

label = gtk_label_new("Hello, world!");

Использование обратных
вызовов для обработки
событий

gtk_widget_show_all(window);

gtk_container_add(GTK_CONTAINER(window), label);
gtk_main();
return 0;
}
1997 — TCL/TK 8.0
●

В этой версии виджеты приняли нативный вид платформы
–

●

К сожалению, пользователям Unix-подобных ОС ничего не
обломилось: нативным видом для них считался вид Motif
–

●

QT и GTK+ были слишком многолики, чтобы считаться «нативным видом», да
к тому же усиленно делили между собой мир Unix-GUI

Тогда же начался закат Tk в мире Unix...
–

●

Приложение выглядело по-разному, в зависимости от того, где оно запущено

…т.к. пользователи там все меньше и меньше пользовались нативным видом
и все больше — богатыми наборами скинов

Ситуацию с Tk попытаются исправить только в 2007, сделав
полноценную поддержку тем в версии 8.5...
–

...и зачем-то принудительно нарушив совместимость на уровне кода
1997 — Netscape IFC становится Swing
(cкролеры в синих пупырышках)
●

●

Поддержка скинов (look-andfeel) и отрисовка чистой Java
Фурор дефолтного скина
среди пользователей Windows

import javax.swing.*;
public class HelloWorld extends JFrame{
public HelloWorld() {
SetDefaultCloseOperation(
DISPOSE_ON_CLOSE);
add(new JLabel("Hello, World!"));
}
public static void main(String[]
args) {
HelloWorld app = new
HelloWorld();
app.pack();
app.setVisible(true);
}
}
Список L&F
пополнили
Ocean в
версии 5
и Nimbus
в версии
6 JDK

Стили Java SE

–

векторная
56Kb
тема
Nimbus
осталась
лучшим
детищем
SUN в дизайне интерфейсов...

–

...и стала основой GTK engine для SUN Java Destkop
Список L&F
пополнили
Ocean в
версии 5
и Nimbus
в версии
6 JDK

Стили Java SE

–

векторная
56Kb
тема
Nimbus
осталась
лучшим
детищем
SUN в дизайне интерфейсов...

–

...и стала основой GTK engine для SUN Java Destkop
Windows - hotspots vs. skins
Windows-приложениям 90-х доступны два способа
редизайна виджетов:
●

Рисовать и подменять по событиям растровые
фрагменты картинок (хотспоты) по примеру web...
–

●

периодически порождает шедевры, но это всегда
штучная работа, которую некуда копировать

Или перирисовывать стандартные виджеты,
вклиниваясь в цикл обработки сообщений
–

по техническим причинам такой идеологическивыверенный и инженерно-обоснованный скин
периодически слетает, показывая фрагменты
стандартных серых кнопок, как в Winamp 2.x :)
1998 — WindowBlinds 1.0
●

Stardock, разработчик оболочки OS/2 Object
Desktop, смогли создать движок скинов для
виджетов WinAPI, почти помещающихся в
128-килобайтный GDI-пул Windows 9x
WindowBlinds после Y2K
●

●

●

В версии 3.0 проблема GDI-пула была
решена (для пользователей Windows 2000)
В результате скины перестали тормозить и
время от времени рушить систему :)
Microsoft скопировала WindowsBlinds в
движке тем Windows XP
–

однако продажи Stardock еще продолжались
за счет лучшей производительности и
использования аппаратно-ускоренной отрисовки
виджетов
~2000 - Apple Cocoa Widgets
API NextSTEP венулся в лоно Apple с
внешним рестайлингом:
2011 — Начал снижаться
интерес к темам GTK и QT
●

Возможные причины:
–

Дефолтный энджин Oxygen, создающий у аналогов легкое чувство
неполноценности

–

Ломка технологий бэкэнда в GTK версии 3.x
Microsoft экспериментирует
с риббонами
Metro helloworld in its best :)
using System;
using Microsoft.Live;
using Microsoft.Live.Controls;
namespace HelloWorldCSharp {
partial class MainPage {
private LiveConnectClient
liveClient;
public MainPage() {
InitializeComponent();
this.btnSignin.SessionChanged +=
OnSessionChanged;
}
private void
OnSessionChanged(object sender,
LiveConnectSessionChangedEventArgs e) {
if (e.Session != null &&
e.Session.Status ==
LiveConnectSessionStatus.Connected){
this.liveClient = new
LiveConnectClient(e.Session);
this.GetMe();
}
else {
this.liveClient = null;
}
}

private void GetMe() {
this.liveClient.GetCompleted += OnGetMe;
this.liveClient.GetAsync("me", null);
}
private void OnGetMe(object
sender, LiveOperationCompletedEventArgs
e) {
this.liveClient.GetCompleted
-= OnGetMe;
if (e.Error == null) {
dynamic result =
e.Result;
this.tbGreeting.Text =
"Hello " + result.first_name + " " +
result.last_name;
}
else {
this.tbError.Text =
e.Error.ToString();
}
}
}
}

More Related Content

What's hot

Memory managment in i os (1)
Memory managment in i os (1)Memory managment in i os (1)
Memory managment in i os (1)it-park
 
PiterPy#3. DSL in Python. How and why?
PiterPy#3. DSL in Python. How and why?PiterPy#3. DSL in Python. How and why?
PiterPy#3. DSL in Python. How and why?Ivan Tsyganov
 
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"Yandex
 
Очень вкусный фрукт Guava
Очень вкусный фрукт GuavaОчень вкусный фрукт Guava
Очень вкусный фрукт GuavaEgor Chernyshev
 
Web осень 2013 лекция 2
Web осень 2013 лекция 2Web осень 2013 лекция 2
Web осень 2013 лекция 2Technopark
 
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в TarantoolИнструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в TarantoolTimur Safin
 
JavaScript. Loops and functions (in russian)
JavaScript. Loops and functions (in russian)JavaScript. Loops and functions (in russian)
JavaScript. Loops and functions (in russian)Mikhail Davydov
 
Что нового в PHP-5.3
Что нового в PHP-5.3 Что нового в PHP-5.3
Что нового в PHP-5.3 phpclub
 
2.4 Использование указателей
2.4 Использование указателей2.4 Использование указателей
2.4 Использование указателейDEVTYPE
 
Язык программирования Go для Perl-программистов
Язык программирования Go для Perl-программистовЯзык программирования Go для Perl-программистов
Язык программирования Go для Perl-программистовAndrew Shitov
 
RxJava+RxAndroid (Lecture 20 – rx java)
RxJava+RxAndroid (Lecture 20 – rx java)RxJava+RxAndroid (Lecture 20 – rx java)
RxJava+RxAndroid (Lecture 20 – rx java)Noveo
 
PHP basic
PHP basicPHP basic
PHP basicNoveo
 
Erlang и n2o. Web-разработка без JavaScript
Erlang и n2o. Web-разработка без JavaScriptErlang и n2o. Web-разработка без JavaScript
Erlang и n2o. Web-разработка без JavaScriptEugene Tataurov
 
Эффективное программирование на NodeJS
Эффективное программирование на NodeJSЭффективное программирование на NodeJS
Эффективное программирование на NodeJSYura Bogdanov
 
Отладка в Erlang, trace/dbg
Отладка в Erlang, trace/dbgОтладка в Erlang, trace/dbg
Отладка в Erlang, trace/dbgYuri Zhloba
 
функции в Java script
функции в Java scriptфункции в Java script
функции в Java scriptViktor Andreev
 
Selenium: приемы работы
Selenium: приемы работыSelenium: приемы работы
Selenium: приемы работыPaul Stashevsky
 

What's hot (20)

Memory managment in i os (1)
Memory managment in i os (1)Memory managment in i os (1)
Memory managment in i os (1)
 
PiterPy#3. DSL in Python. How and why?
PiterPy#3. DSL in Python. How and why?PiterPy#3. DSL in Python. How and why?
PiterPy#3. DSL in Python. How and why?
 
Асинхронный JavaScript
Асинхронный JavaScriptАсинхронный JavaScript
Асинхронный JavaScript
 
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"
 
Очень вкусный фрукт Guava
Очень вкусный фрукт GuavaОчень вкусный фрукт Guava
Очень вкусный фрукт Guava
 
Web осень 2013 лекция 2
Web осень 2013 лекция 2Web осень 2013 лекция 2
Web осень 2013 лекция 2
 
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в TarantoolИнструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
 
XML Magic
XML MagicXML Magic
XML Magic
 
JavaScript. Loops and functions (in russian)
JavaScript. Loops and functions (in russian)JavaScript. Loops and functions (in russian)
JavaScript. Loops and functions (in russian)
 
Что нового в PHP-5.3
Что нового в PHP-5.3 Что нового в PHP-5.3
Что нового в PHP-5.3
 
2.4 Использование указателей
2.4 Использование указателей2.4 Использование указателей
2.4 Использование указателей
 
Язык программирования Go для Perl-программистов
Язык программирования Go для Perl-программистовЯзык программирования Go для Perl-программистов
Язык программирования Go для Perl-программистов
 
PHP7 - что ожидать?
PHP7 - что ожидать?PHP7 - что ожидать?
PHP7 - что ожидать?
 
RxJava+RxAndroid (Lecture 20 – rx java)
RxJava+RxAndroid (Lecture 20 – rx java)RxJava+RxAndroid (Lecture 20 – rx java)
RxJava+RxAndroid (Lecture 20 – rx java)
 
PHP basic
PHP basicPHP basic
PHP basic
 
Erlang и n2o. Web-разработка без JavaScript
Erlang и n2o. Web-разработка без JavaScriptErlang и n2o. Web-разработка без JavaScript
Erlang и n2o. Web-разработка без JavaScript
 
Эффективное программирование на NodeJS
Эффективное программирование на NodeJSЭффективное программирование на NodeJS
Эффективное программирование на NodeJS
 
Отладка в Erlang, trace/dbg
Отладка в Erlang, trace/dbgОтладка в Erlang, trace/dbg
Отладка в Erlang, trace/dbg
 
функции в Java script
функции в Java scriptфункции в Java script
функции в Java script
 
Selenium: приемы работы
Selenium: приемы работыSelenium: приемы работы
Selenium: приемы работы
 

Viewers also liked

Андрэй Захарэвіч — Hack the Hackpad: Першая спроба публічнага кіравання задач...
Андрэй Захарэвіч — Hack the Hackpad: Першая спроба публічнага кіравання задач...Андрэй Захарэвіч — Hack the Hackpad: Першая спроба публічнага кіравання задач...
Андрэй Захарэвіч — Hack the Hackpad: Першая спроба публічнага кіравання задач...Minsk Linux User Group
 
One Year of Porting - Post-mortem of two Linux/SteamOS launches
One Year of Porting - Post-mortem of two Linux/SteamOS launchesOne Year of Porting - Post-mortem of two Linux/SteamOS launches
One Year of Porting - Post-mortem of two Linux/SteamOS launchesLeszek Godlewski
 
Linux as a gaming platform, ideology aside
Linux as a gaming platform, ideology asideLinux as a gaming platform, ideology aside
Linux as a gaming platform, ideology asideLeszek Godlewski
 
Linux as a gaming platform - Errata
Linux as a gaming platform - ErrataLinux as a gaming platform - Errata
Linux as a gaming platform - ErrataLeszek Godlewski
 
Advanced Linux Game Programming
Advanced Linux Game ProgrammingAdvanced Linux Game Programming
Advanced Linux Game ProgrammingLeszek Godlewski
 
GigaSpaces Advantage For Gaming Platforms
GigaSpaces Advantage For Gaming PlatformsGigaSpaces Advantage For Gaming Platforms
GigaSpaces Advantage For Gaming Platformsjimliddle
 

Viewers also liked (7)

Андрэй Захарэвіч — Hack the Hackpad: Першая спроба публічнага кіравання задач...
Андрэй Захарэвіч — Hack the Hackpad: Першая спроба публічнага кіравання задач...Андрэй Захарэвіч — Hack the Hackpad: Першая спроба публічнага кіравання задач...
Андрэй Захарэвіч — Hack the Hackpad: Першая спроба публічнага кіравання задач...
 
Gamedev-grade debugging
Gamedev-grade debuggingGamedev-grade debugging
Gamedev-grade debugging
 
One Year of Porting - Post-mortem of two Linux/SteamOS launches
One Year of Porting - Post-mortem of two Linux/SteamOS launchesOne Year of Porting - Post-mortem of two Linux/SteamOS launches
One Year of Porting - Post-mortem of two Linux/SteamOS launches
 
Linux as a gaming platform, ideology aside
Linux as a gaming platform, ideology asideLinux as a gaming platform, ideology aside
Linux as a gaming platform, ideology aside
 
Linux as a gaming platform - Errata
Linux as a gaming platform - ErrataLinux as a gaming platform - Errata
Linux as a gaming platform - Errata
 
Advanced Linux Game Programming
Advanced Linux Game ProgrammingAdvanced Linux Game Programming
Advanced Linux Game Programming
 
GigaSpaces Advantage For Gaming Platforms
GigaSpaces Advantage For Gaming PlatformsGigaSpaces Advantage For Gaming Platforms
GigaSpaces Advantage For Gaming Platforms
 

Similar to Дмитрий Костюк - Очаровательные серые кнопки: обзор эволюции виджет-тулкитовHistory of widgets

Интуит. Разработка приложений для iOS. Лекция 8. Работа с данными
Интуит. Разработка приложений для iOS. Лекция 8. Работа с даннымиИнтуит. Разработка приложений для iOS. Лекция 8. Работа с данными
Интуит. Разработка приложений для iOS. Лекция 8. Работа с даннымиГлеб Тарасов
 
Школа-Студия разработки приложений для iOS. 5 лекция. Разное
Школа-Студия разработки приложений для iOS. 5 лекция. РазноеШкола-Студия разработки приложений для iOS. 5 лекция. Разное
Школа-Студия разработки приложений для iOS. 5 лекция. РазноеГлеб Тарасов
 
Лекция 12 (часть 2): Языки программирования семейства PGAS: IBM X10
Лекция 12 (часть 2): Языки программирования семейства PGAS: IBM X10Лекция 12 (часть 2): Языки программирования семейства PGAS: IBM X10
Лекция 12 (часть 2): Языки программирования семейства PGAS: IBM X10Mikhail Kurnosov
 
Язык программирования C#
Язык программирования C#Язык программирования C#
Язык программирования C#Dmitri Soshnikov
 
Экскурсия по Flutter SDK
Экскурсия по Flutter SDKЭкскурсия по Flutter SDK
Экскурсия по Flutter SDKSergey Penkovsky
 
Курсы по мобильной разработке. 1 лекция. Знакомство с iOS
Курсы по мобильной разработке. 1 лекция. Знакомство с iOSКурсы по мобильной разработке. 1 лекция. Знакомство с iOS
Курсы по мобильной разработке. 1 лекция. Знакомство с iOSГлеб Тарасов
 
Спецкурс "Современные практики разработки ПО", 2013-2014 уч. год, занятие 2
Спецкурс "Современные практики разработки ПО", 2013-2014 уч. год, занятие 2Спецкурс "Современные практики разработки ПО", 2013-2014 уч. год, занятие 2
Спецкурс "Современные практики разработки ПО", 2013-2014 уч. год, занятие 27bits
 
Взломать Web-сайт на ASP.NET? Сложно, но можно!
Взломать Web-сайт на ASP.NET? Сложно, но можно!Взломать Web-сайт на ASP.NET? Сложно, но можно!
Взломать Web-сайт на ASP.NET? Сложно, но можно!Vladimir Kochetkov
 
Школа-студия разработки для iOS. Лекция 4. Работа с данными
Школа-студия разработки для iOS. Лекция 4. Работа с даннымиШкола-студия разработки для iOS. Лекция 4. Работа с данными
Школа-студия разработки для iOS. Лекция 4. Работа с даннымиГлеб Тарасов
 
Программирование под Maemo
Программирование под MaemoПрограммирование под Maemo
Программирование под Maemodmitryml
 
Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...
Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...
Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...Sigma Software
 
Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksMikhail Kurnosov
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Sergey Platonov
 
automation is iOS development
automation is iOS developmentautomation is iOS development
automation is iOS developmentIvan Trifonov
 
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...Alexey Paznikov
 
Хранение данных в iPhone. (FMDB, SQL-Persistence, CoreData)
Хранение данных в iPhone. (FMDB, SQL-Persistence, CoreData)Хранение данных в iPhone. (FMDB, SQL-Persistence, CoreData)
Хранение данных в iPhone. (FMDB, SQL-Persistence, CoreData)Yandex
 
МАИ, Сети ЭВМ, Лекция №5
МАИ, Сети ЭВМ, Лекция №5МАИ, Сети ЭВМ, Лекция №5
МАИ, Сети ЭВМ, Лекция №5Dima Dzuba
 

Similar to Дмитрий Костюк - Очаровательные серые кнопки: обзор эволюции виджет-тулкитовHistory of widgets (20)

Интуит. Разработка приложений для iOS. Лекция 8. Работа с данными
Интуит. Разработка приложений для iOS. Лекция 8. Работа с даннымиИнтуит. Разработка приложений для iOS. Лекция 8. Работа с данными
Интуит. Разработка приложений для iOS. Лекция 8. Работа с данными
 
Кратко о Mac OS X
Кратко о Mac OS XКратко о Mac OS X
Кратко о Mac OS X
 
Школа-Студия разработки приложений для iOS. 5 лекция. Разное
Школа-Студия разработки приложений для iOS. 5 лекция. РазноеШкола-Студия разработки приложений для iOS. 5 лекция. Разное
Школа-Студия разработки приложений для iOS. 5 лекция. Разное
 
Лекция 12 (часть 2): Языки программирования семейства PGAS: IBM X10
Лекция 12 (часть 2): Языки программирования семейства PGAS: IBM X10Лекция 12 (часть 2): Языки программирования семейства PGAS: IBM X10
Лекция 12 (часть 2): Языки программирования семейства PGAS: IBM X10
 
Язык программирования C#
Язык программирования C#Язык программирования C#
Язык программирования C#
 
msumobi2. Лекция 1
msumobi2. Лекция 1msumobi2. Лекция 1
msumobi2. Лекция 1
 
Экскурсия по Flutter SDK
Экскурсия по Flutter SDKЭкскурсия по Flutter SDK
Экскурсия по Flutter SDK
 
Курсы по мобильной разработке. 1 лекция. Знакомство с iOS
Курсы по мобильной разработке. 1 лекция. Знакомство с iOSКурсы по мобильной разработке. 1 лекция. Знакомство с iOS
Курсы по мобильной разработке. 1 лекция. Знакомство с iOS
 
Спецкурс "Современные практики разработки ПО", 2013-2014 уч. год, занятие 2
Спецкурс "Современные практики разработки ПО", 2013-2014 уч. год, занятие 2Спецкурс "Современные практики разработки ПО", 2013-2014 уч. год, занятие 2
Спецкурс "Современные практики разработки ПО", 2013-2014 уч. год, занятие 2
 
Взломать Web-сайт на ASP.NET? Сложно, но можно!
Взломать Web-сайт на ASP.NET? Сложно, но можно!Взломать Web-сайт на ASP.NET? Сложно, но можно!
Взломать Web-сайт на ASP.NET? Сложно, но можно!
 
Школа-студия разработки для iOS. Лекция 4. Работа с данными
Школа-студия разработки для iOS. Лекция 4. Работа с даннымиШкола-студия разработки для iOS. Лекция 4. Работа с данными
Школа-студия разработки для iOS. Лекция 4. Работа с данными
 
Программирование под Maemo
Программирование под MaemoПрограммирование под Maemo
Программирование под Maemo
 
Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...
Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...
Опыт применения активных объектов во встраиваемых системах. Архитектурные асп...
 
Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building Blocks
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
 
automation is iOS development
automation is iOS developmentautomation is iOS development
automation is iOS development
 
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
 
Хранение данных в iPhone. (FMDB, SQL-Persistence, CoreData)
Хранение данных в iPhone. (FMDB, SQL-Persistence, CoreData)Хранение данных в iPhone. (FMDB, SQL-Persistence, CoreData)
Хранение данных в iPhone. (FMDB, SQL-Persistence, CoreData)
 
МАИ, Сети ЭВМ, Лекция №5
МАИ, Сети ЭВМ, Лекция №5МАИ, Сети ЭВМ, Лекция №5
МАИ, Сети ЭВМ, Лекция №5
 
msumobi2. Лекция 2
msumobi2. Лекция 2msumobi2. Лекция 2
msumobi2. Лекция 2
 

More from Minsk Linux User Group

Vladimir ’mend0za’ Shakhov — Linux firmware for iRMC controller on Fujitsu P...
 Vladimir ’mend0za’ Shakhov — Linux firmware for iRMC controller on Fujitsu P... Vladimir ’mend0za’ Shakhov — Linux firmware for iRMC controller on Fujitsu P...
Vladimir ’mend0za’ Shakhov — Linux firmware for iRMC controller on Fujitsu P...Minsk Linux User Group
 
Святлана Ермаковіч — Вікі-дапаможнік. Як узмацніць беларускую вікі-супольнасць
Святлана Ермаковіч — Вікі-дапаможнік. Як узмацніць беларускую вікі-супольнасцьСвятлана Ермаковіч — Вікі-дапаможнік. Як узмацніць беларускую вікі-супольнасць
Святлана Ермаковіч — Вікі-дапаможнік. Як узмацніць беларускую вікі-супольнасцьMinsk Linux User Group
 
Тимофей Титовец — Elastic+Logstash+Kibana: Архитектура и опыт использования
Тимофей Титовец — Elastic+Logstash+Kibana: Архитектура и опыт использованияТимофей Титовец — Elastic+Logstash+Kibana: Архитектура и опыт использования
Тимофей Титовец — Elastic+Logstash+Kibana: Архитектура и опыт использованияMinsk Linux User Group
 
Андрэй Захарэвіч - Як мы ставілі KDE пад FreeBSD
Андрэй Захарэвіч - Як мы ставілі KDE пад FreeBSDАндрэй Захарэвіч - Як мы ставілі KDE пад FreeBSD
Андрэй Захарэвіч - Як мы ставілі KDE пад FreeBSDMinsk Linux User Group
 
Vitaly ̈_Vi ̈ Shukela - My FOSS projects
Vitaly  ̈_Vi ̈ Shukela - My FOSS projectsVitaly  ̈_Vi ̈ Shukela - My FOSS projects
Vitaly ̈_Vi ̈ Shukela - My FOSS projectsMinsk Linux User Group
 
Alexander Lomov - Cloud Foundry и BOSH: истории из жизни
Alexander Lomov - Cloud Foundry и BOSH: истории из жизниAlexander Lomov - Cloud Foundry и BOSH: истории из жизни
Alexander Lomov - Cloud Foundry и BOSH: истории из жизниMinsk Linux User Group
 
Vikentsi Lapa — How does software testing become software development?
Vikentsi Lapa — How does software testing  become software development?Vikentsi Lapa — How does software testing  become software development?
Vikentsi Lapa — How does software testing become software development?Minsk Linux User Group
 
Михаил Волчек — Свободные лицензии. быть или не быть? Продолжение
Михаил Волчек — Свободные лицензии. быть или не быть? ПродолжениеМихаил Волчек — Свободные лицензии. быть или не быть? Продолжение
Михаил Волчек — Свободные лицензии. быть или не быть? ПродолжениеMinsk Linux User Group
 
Максим Мельников — IPv6 at Home: NAT64, DNS64, OpenVPN
Максим Мельников — IPv6 at Home: NAT64, DNS64, OpenVPNМаксим Мельников — IPv6 at Home: NAT64, DNS64, OpenVPN
Максим Мельников — IPv6 at Home: NAT64, DNS64, OpenVPNMinsk Linux User Group
 
Слава Машканов — “Wubuntu”: Построение гетерогенной среды Windows+Linux на н...
Слава Машканов — “Wubuntu”: Построение гетерогенной среды  Windows+Linux на н...Слава Машканов — “Wubuntu”: Построение гетерогенной среды  Windows+Linux на н...
Слава Машканов — “Wubuntu”: Построение гетерогенной среды Windows+Linux на н...Minsk Linux User Group
 
MajorDoMo: Открытая платформа Умного Дома
MajorDoMo: Открытая платформа Умного ДомаMajorDoMo: Открытая платформа Умного Дома
MajorDoMo: Открытая платформа Умного ДомаMinsk Linux User Group
 
Максим Салов - Отладочный монитор
Максим Салов - Отладочный мониторМаксим Салов - Отладочный монитор
Максим Салов - Отладочный мониторMinsk Linux User Group
 
Максим Мельников - FOSDEM 2014 overview
Максим Мельников - FOSDEM 2014 overviewМаксим Мельников - FOSDEM 2014 overview
Максим Мельников - FOSDEM 2014 overviewMinsk Linux User Group
 
Константин Шевцов - Пара слов о Jenkins
Константин Шевцов - Пара слов о JenkinsКонстантин Шевцов - Пара слов о Jenkins
Константин Шевцов - Пара слов о JenkinsMinsk Linux User Group
 
Ермакович Света - Операция «Пингвин»
Ермакович Света - Операция «Пингвин»Ермакович Света - Операция «Пингвин»
Ермакович Света - Операция «Пингвин»Minsk Linux User Group
 
Михаил Волчек - Смогут ли беларусы вкусить плоды Творческих Общин? Creative C...
Михаил Волчек - Смогут ли беларусы вкусить плоды Творческих Общин? Creative C...Михаил Волчек - Смогут ли беларусы вкусить плоды Творческих Общин? Creative C...
Михаил Волчек - Смогут ли беларусы вкусить плоды Творческих Общин? Creative C...Minsk Linux User Group
 
Алексей Туля - А нужен ли вам erlang?
Алексей Туля - А нужен ли вам erlang?Алексей Туля - А нужен ли вам erlang?
Алексей Туля - А нужен ли вам erlang?Minsk Linux User Group
 
Виктор Сергейчик - Как пользоваться PGP безопасно и правильно. Вводная к Keys...
Виктор Сергейчик - Как пользоваться PGP безопасно и правильно. Вводная к Keys...Виктор Сергейчик - Как пользоваться PGP безопасно и правильно. Вводная к Keys...
Виктор Сергейчик - Как пользоваться PGP безопасно и правильно. Вводная к Keys...Minsk Linux User Group
 

More from Minsk Linux User Group (20)

Vladimir ’mend0za’ Shakhov — Linux firmware for iRMC controller on Fujitsu P...
 Vladimir ’mend0za’ Shakhov — Linux firmware for iRMC controller on Fujitsu P... Vladimir ’mend0za’ Shakhov — Linux firmware for iRMC controller on Fujitsu P...
Vladimir ’mend0za’ Shakhov — Linux firmware for iRMC controller on Fujitsu P...
 
Святлана Ермаковіч — Вікі-дапаможнік. Як узмацніць беларускую вікі-супольнасць
Святлана Ермаковіч — Вікі-дапаможнік. Як узмацніць беларускую вікі-супольнасцьСвятлана Ермаковіч — Вікі-дапаможнік. Як узмацніць беларускую вікі-супольнасць
Святлана Ермаковіч — Вікі-дапаможнік. Як узмацніць беларускую вікі-супольнасць
 
Тимофей Титовец — Elastic+Logstash+Kibana: Архитектура и опыт использования
Тимофей Титовец — Elastic+Logstash+Kibana: Архитектура и опыт использованияТимофей Титовец — Elastic+Logstash+Kibana: Архитектура и опыт использования
Тимофей Титовец — Elastic+Logstash+Kibana: Архитектура и опыт использования
 
Андрэй Захарэвіч - Як мы ставілі KDE пад FreeBSD
Андрэй Захарэвіч - Як мы ставілі KDE пад FreeBSDАндрэй Захарэвіч - Як мы ставілі KDE пад FreeBSD
Андрэй Захарэвіч - Як мы ставілі KDE пад FreeBSD
 
Vitaly ̈_Vi ̈ Shukela - My FOSS projects
Vitaly  ̈_Vi ̈ Shukela - My FOSS projectsVitaly  ̈_Vi ̈ Shukela - My FOSS projects
Vitaly ̈_Vi ̈ Shukela - My FOSS projects
 
Vitaly ̈_Vi ̈ Shukela - Dive
Vitaly  ̈_Vi ̈ Shukela - DiveVitaly  ̈_Vi ̈ Shukela - Dive
Vitaly ̈_Vi ̈ Shukela - Dive
 
Alexander Lomov - Cloud Foundry и BOSH: истории из жизни
Alexander Lomov - Cloud Foundry и BOSH: истории из жизниAlexander Lomov - Cloud Foundry и BOSH: истории из жизни
Alexander Lomov - Cloud Foundry и BOSH: истории из жизни
 
Vikentsi Lapa — How does software testing become software development?
Vikentsi Lapa — How does software testing  become software development?Vikentsi Lapa — How does software testing  become software development?
Vikentsi Lapa — How does software testing become software development?
 
Михаил Волчек — Свободные лицензии. быть или не быть? Продолжение
Михаил Волчек — Свободные лицензии. быть или не быть? ПродолжениеМихаил Волчек — Свободные лицензии. быть или не быть? Продолжение
Михаил Волчек — Свободные лицензии. быть или не быть? Продолжение
 
Максим Мельников — IPv6 at Home: NAT64, DNS64, OpenVPN
Максим Мельников — IPv6 at Home: NAT64, DNS64, OpenVPNМаксим Мельников — IPv6 at Home: NAT64, DNS64, OpenVPN
Максим Мельников — IPv6 at Home: NAT64, DNS64, OpenVPN
 
Слава Машканов — “Wubuntu”: Построение гетерогенной среды Windows+Linux на н...
Слава Машканов — “Wubuntu”: Построение гетерогенной среды  Windows+Linux на н...Слава Машканов — “Wubuntu”: Построение гетерогенной среды  Windows+Linux на н...
Слава Машканов — “Wubuntu”: Построение гетерогенной среды Windows+Linux на н...
 
MajorDoMo: Открытая платформа Умного Дома
MajorDoMo: Открытая платформа Умного ДомаMajorDoMo: Открытая платформа Умного Дома
MajorDoMo: Открытая платформа Умного Дома
 
Максим Салов - Отладочный монитор
Максим Салов - Отладочный мониторМаксим Салов - Отладочный монитор
Максим Салов - Отладочный монитор
 
Максим Мельников - FOSDEM 2014 overview
Максим Мельников - FOSDEM 2014 overviewМаксим Мельников - FOSDEM 2014 overview
Максим Мельников - FOSDEM 2014 overview
 
Константин Шевцов - Пара слов о Jenkins
Константин Шевцов - Пара слов о JenkinsКонстантин Шевцов - Пара слов о Jenkins
Константин Шевцов - Пара слов о Jenkins
 
Ермакович Света - Операция «Пингвин»
Ермакович Света - Операция «Пингвин»Ермакович Света - Операция «Пингвин»
Ермакович Света - Операция «Пингвин»
 
Михаил Волчек - Смогут ли беларусы вкусить плоды Творческих Общин? Creative C...
Михаил Волчек - Смогут ли беларусы вкусить плоды Творческих Общин? Creative C...Михаил Волчек - Смогут ли беларусы вкусить плоды Творческих Общин? Creative C...
Михаил Волчек - Смогут ли беларусы вкусить плоды Творческих Общин? Creative C...
 
Vikentsi Lapa - Tools for testing
Vikentsi Lapa - Tools for testingVikentsi Lapa - Tools for testing
Vikentsi Lapa - Tools for testing
 
Алексей Туля - А нужен ли вам erlang?
Алексей Туля - А нужен ли вам erlang?Алексей Туля - А нужен ли вам erlang?
Алексей Туля - А нужен ли вам erlang?
 
Виктор Сергейчик - Как пользоваться PGP безопасно и правильно. Вводная к Keys...
Виктор Сергейчик - Как пользоваться PGP безопасно и правильно. Вводная к Keys...Виктор Сергейчик - Как пользоваться PGP безопасно и правильно. Вводная к Keys...
Виктор Сергейчик - Как пользоваться PGP безопасно и правильно. Вводная к Keys...
 

Дмитрий Костюк - Очаровательные серые кнопки: обзор эволюции виджет-тулкитовHistory of widgets

  • 2. 1983 - Apple Lisa Workshop ● Разрабатывать софт для Apple Lisa предполагалось в отдельной ОС с полноэкранной консолью и единственным GUIприложением - текстовым редактором... – ● ...писать код, компилировать, а потом перезагружаться :) Софт писался на Паскале, но требовал от программиста глубоких знаний архитектуры ОС – упрощенный фреймворк виджетов должен был называться Lisa ToolKit, но как раз к его выпуску платформу Lisa закрыли
  • 3. Среда разработки была консольной, а из GUIинструментов имела лишь текстовый редактор
  • 4. 1982 - Andrew Project :) ● Сетевая компьютерная среда университета Карнеги-Меллон включала Andrew User Interface System (AUIS) – Andrew User Environment (AUE) — редактор, справка, весь GUI – Andrew Toolkit (ATK) — коллекция встраиваемых и форматируемых объектов – The Andrew Message System (AMS) — почта и BBS-софт
  • 5. Andrew toolkit in it's best :)
  • 6. 1988 ­ Project Athena (XAW) ● ● Проект MTI, DEC и IBM по разработке распределенной вычислительной среды кампуса ● привел к созданию X Window System, Kerberos, Zephyr... Впервые словом "виджеты" обозначены элементы управления
  • 10. Motif widgets & helloworld #include <Xm/XmAll.h> void main(int argc, char *argv[]) { Widget toplevel, main_w, button; XtAppContext app; XtSetLanguageProc(NULL, NULL, NULL); toplevel = XtVaAppInitialize(&app, "main", NULL, 0, &argc, argv, NULL, NULL); main_w = XtVaCreateManagedWidget("main_w", xmMainWindowWidgetClass, toplevel, XmNscrollingPolicy, XmAUTOMATIC, NULL); button = XtVaCreateWidget("Hello World", xmLabelWidgetClass, main_w, NULL); XtManageChild(button); XtRealizeWidget(toplevel); XtAppMainLoop(app); }
  • 11. 1985 - WinAPI ● Тулкит, задуманный как запредельно гибкий в программировании – – ● Программист может взаимодействовать со всей внутренней архитектурой... ...и из-за этого вынужден самостоятельно выполнять массу низкоуровневых операций Windows 1.0 SDK содержал самый скандальный helloworld в истории GUI... – ...cостоявший из hello.c (150 строк) и hello.rc (20 строк) – при том, что весь WinAPI в тот момент включал 450 системных вызовов :)
  • 12. /* Hello.c Hello Application Windows Toolkit Version 1.03 Copyright (c) Microsoft 1985,1986 */ #include "windows.h" #include "hello.h" char szAppName[10]; char szAbout[10]; char szMessage[15]; int MessageLength; static HANDLE hInst; FARPROC lpprocAbout; long FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG); BOOL FAR PASCAL About( hDlg, message, wParam, lParam ) HWND hDlg; unsigned message; WORD wParam; LONG lParam; /* Procedure called when the application is loaded for the first time */ BOOL HelloInit( hInstance ) HANDLE hInstance; { PWNDCLASS pHelloClass; /* Load strings from resource */ LoadString( hInstance, IDSNAME, (LPSTR)szAppName, 10 ); LoadString( hInstance, IDSABOUT, (LPSTR)szAbout, 10 ); MessageLength = LoadString( hInstance, IDSTITLE, (LPSTR)szMessage, 15 ); pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) ); pHelloClass->hCursor = LoadCursor( NULL, IDC_ARROW ); pHelloClass->hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(HELLOICON) );
  • 13. int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow ) HANDLE hInstance, hPrevInstance; LPSTR lpszCmdLine; int cmdShow; { MSG msg; HWND hWnd; HMENU hMenu; if (!hPrevInstance) { /* Call initialization procedure if this is the first instance */ if (!HelloInit( hInstance )) return FALSE; } else { /* Copy data from previous instance */ GetInstanceData( hPrevInstance, (PSTR)szAppName, 10 ); GetInstanceData( hPrevInstance, (PSTR)szAbout, 10 ); GetInstanceData( hPrevInstance, (PSTR)szMessage, 15 ); GetInstanceData( hPrevInstance,
  • 14. /* Insert "About..." into system menu */ hMenu = GetSystemMenu(hWnd, FALSE); ChangeMenu(hMenu, 0, NULL, 999, MF_APPEND | MF_SEPARATOR); ChangeMenu(hMenu, 0, (LPSTR)szAbout, IDSABOUT, MF_APPEND | MF_STRING); case WM_DESTROY: PostQuitMessage( 0 /* Make window visible according to the way the app is ); activated */ break; ShowWindow( hWnd, cmdShow ); UpdateWindow( hWnd ); case WM_PAINT: BeginPaint( hWnd, /* Polling messages from event queue */ while (GetMessage((LPMSG)&msg, NULL, 0, 0)) { (LPPAINTSTRUCT)&ps ); HelloPaint( ps.hdc ); TranslateMessage((LPMSG)&msg); EndPaint( hWnd, DispatchMessage((LPMSG)&msg); (LPPAINTSTRUCT)&ps ); } break; return (int)msg.wParam; default: } return DefWindowProc( hWnd, message, wParam, /* Procedures which make up the window class. */ long FAR PASCAL HelloWndProc( hWnd, message, lParam );
  • 15. 1987 - NextSTEP ● ● API на основе Objective C Нативная поддержка интроспекции объектов и первая RADсистема
  • 16. GNUStep helloworld #include "AppController.h" #include <AppKit/AppKit.h> int main(int argc, const char *argv[]) `{ NSAutoreleasePool *pool; AppController *delegate; pool = [[NSAutoreleasePool alloc] init]; #include <AppKit/AppKit.h> - (void) applicationWillFinishLaunching: (NSNotification *) not { /* Create Menu */ NSMenu *menu; NSMenu *info; menu = [NSMenu new]; [NSApp setDelegate: delegate]; [menu addItemWithTitle: @"Info" return NSApplicationMain (argc, argv); } /* Create Window */ window = [[NSWindow alloc] initWithContentRect: NSMakeRect(300, 300, 200, 100) (NSTitledWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask) NSBackingStoreBuffered [menu addItemWithTitle: @"Hide" [window setTitle: @"Hello World"]; keyEquivalent: @"h"]; #define _AppController_H_ #include <Foundation/NSObject.h> @class NSWindow; @class NSTextField; @class NSNotification; action: @selector(terminate:) NSWindow *window; NSTextField *label; } /* Create Label */ label = [[NSTextField alloc] initWithFrame: NSMakeRect(30, 30, 80, 30)]; [label setSelectable: NO]; keyEquivalent: @"q"]; [label setBezeled: NO]; info = [NSMenu new]; [label setDrawsBackground: NO]; [info addItemWithTitle: @"Info Panel..." [label setStringValue: @"Hello World"]; action: @selector(orderFrontStandardInfoPanel:) [[window contentView] addSubview: label]; keyEquivalent: @""]; [info addItemWithTitle: @"Preferences" action: NULL @interface AppController : NSObject { keyEquivalent: @""]; RELEASE(label); } - (void) applicationDidFinishLaunching: (NSNotification *) not { [window makeKeyAndOrderFront: self]; [info addItemWithTitle: @"Help" action: @selector (orderFrontHelpPanel:) keyEquivalent: @"?"]; } - (void) dealloc { RELEASE(window); - (void)applicationWillFinishLaunching:(NSNotification *) not; - (void)applicationDidFinishLaunching:(NSNotification *) not; [menu setSubmenu: info forItem: [menu itemWithTitle:@"Info"]]; @end #endif /* _AppController_H_ */ backing: defer: YES]; action: @selector(hide:) [menu addItemWithTitle: @"Quit" #ifndef _AppController_H_ styleMask: action: NULL keyEquivalent: @""]; RELEASE(pool); RELEASE(menu); @implementation AppController delegate = [[AppController alloc] init]; [NSApplication sharedApplication]; [NSApp setMainMenu:menu]; [super dealloc]; } RELEASE(info); @end
  • 17. 1990 - AmigaOS 2.0 ● Базовая библиотека GUI Intuition расширена тулкитом стандартных виджетов gadtools.library и объектноориентированным API BOOPSI – ● Основыми проблемами GUI остаются бедный запас виджетов, фиксированные размеры шрифтов и окон В 1992 появляется сторонний тулкит MUI, умеющий кастомизировать виджеты – Свободный клон MUI под названием Zune входит в состав AROS (свободного клона AmigaOS) #include <libraries/mui.h> #include <proto/muimaster.h> // Sample application: ApplicationObject, SubWindow, WindowObject, WindowContents, VGroup, Child, TextObject, MUIA_Text_Contents, "Hello World!", End, End, End, End;
  • 18.
  • 19. 199x — от Win16 к Win32
  • 20. Тулкиты-обёртки Большинство тулкитов-оберток появляется под Windows. Цели их создания: ● ● ● Обёртки стандартных виджетов: ● MFC (C++) Упрощение исходного кода ● AWT (Java) Упраление размещением элементов ● wxWidgets (C++) ● ... Обработкой событий, многопоточность и др. Альтернативные тулкиты: Легкая отладка и упрощение кода ● ● Qt (C++, кастомизируемый) ● Многоплатформенность ● GTK+ (C, кастомизируемый) ● FOX (C++, Win95-sytle)... – Некоторые задуманы как способ сделать программу, которую можно собрать под любую из мэйнстримных ОС ● FLTK (C++/embedded, кастомизируемый на 3-4 темы)
  • 22. 1991 — Tcl/Tk ● ● ● Tk родился в университете Беркли как реакция на слишком сложную разработу интерфейсов с Motif, и был задуман предельно простым в программировани Реализован как одно из расширений скриптового языка Tcl Tcl/Tk был довольно быстро портирован на другие платформы, и до 1997 года пугал их пользователей визуальным стилем Motif #!/usr/bin/wish button .hello -text "Hello, World!" -command { exit } pack .hello
  • 23. 1992 - MFC #include <afxwin.h> #define IDC_BUTTON 100 class CButtonApp : public CWinApp { public: virtual BOOL InitInstance(); }; ● ● ● Первая и наиболее успешная обертка к WinAPI C++ во всей красе: наследование от класса окна и т.д. События связываются с обработчиками с помощью макросов CButtonApp ButtonApp; class CButtonWindow : public CFrameWnd { CButton *button; public: CButtonWindow(); afx_msg void HandleButton(); DECLARE_MESSAGE_MAP() }; void CButtonWindow::HandleButton() { MessageBox("Hello World", "Hello!", MB_ICONEXCLAMATION ); } BEGIN_MESSAGE_MAP(CButtonWindow, CFrameWnd) ON_BN_CLICKED(IDC_BUTTON, HandleButton) END_MESSAGE_MAP() BOOL CButtonApp::InitInstance() { m_pMainWnd = new CButtonWindow(); m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CButtonWindow::CButtonWindow() { CRect r; Create(NULL, "CButton Tests", WS_OVERLAPPEDWINDOW, CRect(0,0,200,200)); GetClientRect(&r); r.InflateRect(-20,-20); button = new CButton(); button->Create("Push me", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, r, this, IDC_BUTTON); }
  • 25. 1995 — Java AWT ● ● ● ● Кроссплатформенная Java-обёртка над нативными виджетами Для полной нативности Sun Microsystems решительно отказывалась включать в набор виджеты, остутствующие в какой-либо из платформ Зато пользователи получили автоматическое размещение компонент с помощью шести layout managers (аналог geometry managers из Tk) Обработчики событий реализуются переопределением функций из интерфейсов (упрощенный аналог множественного наследования)
  • 26. 1995 - Qt #include <qapplication.h> ● ● ● C++ с предкомпиляцией специальным кодогенератором (moc), обрабатывающим дополнительные Qtабстракции семь менеджеров размещения виджетов Абстракции слот и сигнал для обработки событий #include <qmainwindow.h> #include <qpushbutton.h> #include <qfont.h> int main(int argc, char **argv) { QApplication myApp(argc, argv); QMainWindow* myWin = new QMainWindow(0, 0, 0); myWin->resize(500, 300); myWin->move(200, 100); QPushButton* quitButton = new QPushButton("Quit", myWin); quitButton->resize(60, 30); quitButton->move(220, 135); quitButton->setFont(QFont("Times", 18, QFont::Bold)); QObject::connect(quitButton, SIGNAL(clicked()), &myApp, SLOT(quit())); myApp.setMainWidget(myWin); myWin->show(); return myApp.exec(); }
  • 27. 1997 — GTK (сначала без +) ● ● ● ● Изначально создавался как замена Motif в GIMP 0.60 К версии GIMP 0.99 тулкит переписали, добавили ООП и плюсик в названии #include <gtk/gtk.h> int main (int argc, char *argv[]) { GtkWidget *window; GtkWidget *label; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "Hello, world!"); g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); 3 менеджера размещения label = gtk_label_new("Hello, world!"); Использование обратных вызовов для обработки событий gtk_widget_show_all(window); gtk_container_add(GTK_CONTAINER(window), label); gtk_main(); return 0; }
  • 28. 1997 — TCL/TK 8.0 ● В этой версии виджеты приняли нативный вид платформы – ● К сожалению, пользователям Unix-подобных ОС ничего не обломилось: нативным видом для них считался вид Motif – ● QT и GTK+ были слишком многолики, чтобы считаться «нативным видом», да к тому же усиленно делили между собой мир Unix-GUI Тогда же начался закат Tk в мире Unix... – ● Приложение выглядело по-разному, в зависимости от того, где оно запущено …т.к. пользователи там все меньше и меньше пользовались нативным видом и все больше — богатыми наборами скинов Ситуацию с Tk попытаются исправить только в 2007, сделав полноценную поддержку тем в версии 8.5... – ...и зачем-то принудительно нарушив совместимость на уровне кода
  • 29. 1997 — Netscape IFC становится Swing (cкролеры в синих пупырышках) ● ● Поддержка скинов (look-andfeel) и отрисовка чистой Java Фурор дефолтного скина среди пользователей Windows import javax.swing.*; public class HelloWorld extends JFrame{ public HelloWorld() { SetDefaultCloseOperation( DISPOSE_ON_CLOSE); add(new JLabel("Hello, World!")); } public static void main(String[] args) { HelloWorld app = new HelloWorld(); app.pack(); app.setVisible(true); } }
  • 30. Список L&F пополнили Ocean в версии 5 и Nimbus в версии 6 JDK Стили Java SE – векторная 56Kb тема Nimbus осталась лучшим детищем SUN в дизайне интерфейсов... – ...и стала основой GTK engine для SUN Java Destkop
  • 31. Список L&F пополнили Ocean в версии 5 и Nimbus в версии 6 JDK Стили Java SE – векторная 56Kb тема Nimbus осталась лучшим детищем SUN в дизайне интерфейсов... – ...и стала основой GTK engine для SUN Java Destkop
  • 32. Windows - hotspots vs. skins Windows-приложениям 90-х доступны два способа редизайна виджетов: ● Рисовать и подменять по событиям растровые фрагменты картинок (хотспоты) по примеру web... – ● периодически порождает шедевры, но это всегда штучная работа, которую некуда копировать Или перирисовывать стандартные виджеты, вклиниваясь в цикл обработки сообщений – по техническим причинам такой идеологическивыверенный и инженерно-обоснованный скин периодически слетает, показывая фрагменты стандартных серых кнопок, как в Winamp 2.x :)
  • 33.
  • 34.
  • 35. 1998 — WindowBlinds 1.0 ● Stardock, разработчик оболочки OS/2 Object Desktop, смогли создать движок скинов для виджетов WinAPI, почти помещающихся в 128-килобайтный GDI-пул Windows 9x
  • 36. WindowBlinds после Y2K ● ● ● В версии 3.0 проблема GDI-пула была решена (для пользователей Windows 2000) В результате скины перестали тормозить и время от времени рушить систему :) Microsoft скопировала WindowsBlinds в движке тем Windows XP – однако продажи Stardock еще продолжались за счет лучшей производительности и использования аппаратно-ускоренной отрисовки виджетов
  • 37.
  • 38. ~2000 - Apple Cocoa Widgets API NextSTEP венулся в лоно Apple с внешним рестайлингом:
  • 39. 2011 — Начал снижаться интерес к темам GTK и QT ● Возможные причины: – Дефолтный энджин Oxygen, создающий у аналогов легкое чувство неполноценности – Ломка технологий бэкэнда в GTK версии 3.x
  • 41. Metro helloworld in its best :) using System; using Microsoft.Live; using Microsoft.Live.Controls; namespace HelloWorldCSharp { partial class MainPage { private LiveConnectClient liveClient; public MainPage() { InitializeComponent(); this.btnSignin.SessionChanged += OnSessionChanged; } private void OnSessionChanged(object sender, LiveConnectSessionChangedEventArgs e) { if (e.Session != null && e.Session.Status == LiveConnectSessionStatus.Connected){ this.liveClient = new LiveConnectClient(e.Session); this.GetMe(); } else { this.liveClient = null; } } private void GetMe() { this.liveClient.GetCompleted += OnGetMe; this.liveClient.GetAsync("me", null); } private void OnGetMe(object sender, LiveOperationCompletedEventArgs e) { this.liveClient.GetCompleted -= OnGetMe; if (e.Error == null) { dynamic result = e.Result; this.tbGreeting.Text = "Hello " + result.first_name + " " + result.last_name; } else { this.tbError.Text = e.Error.ToString(); } } } }