metarhia / console

Constructivism in UI rendering
https://metarhia.com
26 stars 0 forks source link

DSL for User Interface #1

Open tshemsedinov opened 8 years ago

tshemsedinov commented 8 years ago

Main classes:

Control properties:

{
  name, owner, parent, visible, enabled,
  align: (top, bottom, left, right, client, none),
  x, y, width, height, hint, scrollable
}

Control properties:

{ click, hold, focus, leave, over, exit, hide, show, scroll }

Theme properties:

{
  normal: {
    font: { face, size, ... },
    colors: { text, back, border, shadow... },
  },
  selected: { ... },
  disabled: { ... },
  focused: { ... }
}

Basic controls:

Additional controls:

tshemsedinov commented 8 years ago

Прокомментируйте и добавьте свойств по реализации для ветхого веба @aqrln, @sun1x, для iOS @Gagnant, @GYFK, для Android @lidaamber и Qt @NechaiDO, @belochub

belochub commented 8 years ago

Мне кажется, что нужно в Switch тоже добавить value (по аналогии с Check), а в Check и Radio добавить text, чтобы рендерер сам Label рядом рисовал, и не надо было бы подгонять это вручную. И ещё, в Control properties не должна входить theme тоже? Для случаев, если кому-то необходимо будет задать другой какой-то цвет или шрифт для какого-то конкретного одного контрола, например?

snanovskyi commented 8 years ago

Нужно что-то добавить для реализации адаптивности. Допустим, есть 2 контейнера: навигация + контент. Mobile device:

[Navigation]
[Content   ]

Desktop(or landscape tablet): [Navigation][Content ]

Можно сделать набор лейаутов:

{
  type: 'container',
  layout: 'someLayout'
}

Или задавать каждому свой стиль в зависимости от девайса:

{
  type: 'container',
  style: {
    mobile: {...},
    tablet: {...},
    desktop: {...}
  }
}
tshemsedinov commented 8 years ago

@sun1x я думаю, что нужно сделать два варианта;

  1. Когда есть условные значения свойств, например:
{ align: { k0: 'top', k1: 'left', k2: 'left' ... } }
  1. Когда есть несколько разных лейаутов вообще:
{
  k1: { panel1: { type: 'panel', align: 'top' } },
  k2: { panel1: { type: 'panel', align: 'left' } }
}
tshemsedinov commented 8 years ago

Какие есть best practices? @aqrln, @sun1x, @Gagnant, @GYFK, @lidaamber, @NechaiDO, @belochub по альтернативным лейаутам в разных разрешениях?

lidaamber commented 8 years ago

@tshemsedinov в Android как единица измерения используется dip (density-independent pixel), что позволяет практически одинаково отображать тот или иной элемент разметки на различных устройствах с разным разрешением. Для горизонтального отображения экрана, тем более крупного, желательно делать альтернативный вариант основной разметки, т.к. перевернутый и растянутый вертикальный будет не очень.

tshemsedinov commented 8 years ago

Можно ограничиться всегда вариантами: phone, tablet, laptop и двумя ориентациями: portrait и landscape, это же полностью покрывает все? (или лучше vertical, horizontal)

lidaamber commented 8 years ago

@tshemsedinov думаю, да Edit: если vertical/horizontal, то было бы хорошо указывать, с какой ширины начиная применять этот horizontal (к примеру, на телефоне горизонтальный вариант приложения и вариант для планшета будут очень отличаться)

tshemsedinov commented 8 years ago

@sun1x, @Gagnant, @GYFK, @lidaamber попробуйте сделать рендеринг примера https://github.com/metarhia/Console/blob/master/Examples/example1.jstp

А @aqrln, @NechaiDO, @belochub, попробуйте сделать еще несколько разных примеров.

2All: я думаю, что поля { x, y } не нужны, мы сделаем { top, bottom, left, right, width, height } из которых некоторые можно установить, а некоторые должны сами пересчитаться в зависимости от других полей позиционирования и от align, но это нужно продумать подробнее. Сделать кейсы, например: если стоят поля { align: 'top', height: 10 }, то понятно, что остальные должны быть выставелны по дефолту так: { align: 'top', top: 0, left: 0, right: 0, width:<ширина экрана>, height: 10 }, а поле bottom должно быть null.

snanovskyi commented 8 years ago

@tshemsedinov как считать размеры? Что есть единицей измерения?

tshemsedinov commented 8 years ago

@sun1x мне @lidaamber говорила про density-independent pixel для Android, думаю, это хорошая идея, все держать в них или в похожих единицах и пересчитывать в физические пиксели при отрисовке. @Gagnant и @GYFK что там в iOS?

GYFK commented 8 years ago

@tshemsedinov идея та же, что и у @lidaamber , только называется это Point. Перевод примерно так выглядит

calculatingandroidiospixels

aqrln commented 8 years ago

Мне не особо нравится идея с абсолютным позиционированием элементов, ведь размеры экранов на всех устройствах разные. Density-independent pixels, насколько я понял, решают проблему физического размера элементов на экранах с маленькой и высокой плотностью пикселей, но не адаптивного лейаута. Поэтому может возникнуть ситуация, когда на маленьком экране UI не будет помещаться на экране, а на большом будет свободное место справа и снизу. Нужна какая-то резиновая/адаптивная сетка, как в любом современном десктопном фреймворке для построения UI или Flexbox в CSS.

aqrln commented 8 years ago

Хотя если мы отказались от { x, y } и отталкиваемся от краёв экрана, то это не совсем абсолютное позиционирование, но сути дела это не меняет. Да, не будет пустых мест справа и снизу, но лейаут всё равно может очень сильно поплыть. Нужно как-то указывать структуру формы и положение элементов относительно отдельных её блоков.

aqrln commented 8 years ago

@sun1x единица измерения — как бы пиксель. В браузерах ведь тоже 1px ≠ физическому пикселю, а зависит от DPI экрана и масштаба страницы.

tshemsedinov commented 8 years ago

@aqrln мы будем иметь несколько таких лейаутов, наприемр:

{
  control: 'panel',
  mobile: { align: 'top', height: 10 },
  tablet: { align: 'top', height: 20 },
  desktop: { align: 'left', width: 25 }
}

или даже

{
  control: 'panel',
  mobile: {
    vertical: { align: 'top', height: 10 },
    horizontal: { align: 'left', height: 15 }
  },
  tablet: {
    vertical: { align: 'top', height: 20 },
    horizontal: { align: 'left', height: 20 }
  }
}

или может так:

{
  layouts: {
    small: {
      resolutions: [ 'mobile/vertical', 'tablet/horizontal' ],
      controls: {
        tools: { control: 'panel', align: 'top', height: 10 },
        view: { control: 'panel', align: 'client', top: 10 }
      }
    },
    normal: {
      resolutions: [ 'laptop', 'tablet/vertical', 'tablet/horizontal' ],
      controls: {
        tools: { control: 'panel', align: 'left', width: 15 },
        view: { control: 'panel', align: 'client', left: 15 }
      }
    },
    fullscreen: {
      resolutions: [ '!mobile' ],
      controls: {
        tools: { control: 'panel', align: 'left', width: 15, visible: false },
        view: { control: 'panel', align: 'client' }
      }
    }
  }
}

Не вижу причин, почему такая верстка может рвать экран или где она может быть плохой. Конечно, есть много альтернативных синтаксисов и записей, и не хотелось бы поддерживать много вариантов записи, чтобы не запутаться самим и ни кого не запутать, но думаю, что принципиально это будет работать, а оставить 1-2 варианта записи мы можем вполне. Один варант - это когда внутри контроле прописываются варианты его лейаута, а второй вариант, это когда для всего экрана или для всего приложения есть несколько лейаутов.

Еще хорошая идея, думаю, если мы разделим описание формы: отдельно лейауты, а отдельно все остальные свойства. Это чтоб уменьшить дублирование. Более важными считаем свойства из лейаутов, т.е. они переопределяют свойства контролов, описанных дефолтно. Так мы всегда читаем свойство из дефолта, потом ищем в лейауте, если там есть, то берем переопределенное, если нет, то берем из описания контрола.

tshemsedinov commented 8 years ago

Не хотелось бы сказываться в гридовую верстку, как случилось с ветхим вебом, это костыль по моему, и без нее можно сделать красивее, но нужно придумать примеров и сравнить.

tshemsedinov commented 8 years ago

fyi @lundibundi