Вопросы по LCL

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Re: Вопросы по LCL

Сообщение А.Н. » 23.06.2010 14:44:49

Базовый класс (простая линия) знает только об одной линии. а тут их 3. Метод выделения базового класса проверял попадание средней линии под мышь, тут нужно еще проверить линии выше и ниже.

Тогда, я могу предположить, следует использовать не наследование, а включение объектов класса "линия" в новый класс "СУПЕРЛИНИЯ".
Например, есть базовые классы:
1.) Примитив.
2.) Композитный объект.

Примитив - это линии, прямоугольники и всё прочее, что у вас является примитивом.
Композитный объект - это базовый класс для всех остальных "пользовательских" объектов.
Композитный объект содержит массив примитивов. Всё рисование сводится к добавлению примитива в массив и заданию его относительных координат.
При вызове метода отрисовки, метод-инициализатор переводит начальные координаты в абсолютные (ну, в случае с OpenGL, это не требуется).
Затем, производится проход по массиву объектов и вызов метода отрисовки каждого объекта.
Как вариант, перевод координат может делать класс "Примитив".

чето в пункты а и б я не въехал)).

б - это мой бред.
а - это просто "обведение" объектов ломаной. Точки отрезков ломаной берутся из "выступающих" точек примитивов. При том, что примитивы не пересекаются.

в - вроде понял, но он не честный. площадь прямоугольника может быть гораздо больше площади выделяемого объекта (если он вытянут и расположен по диагонали) - соответствеео выделение будет работать не правильно.

Он честный. :) Пользователь-то об этом будет знать. Но он не очень удобный. Крайний пример - просто диагональная линия.

выделение должно быть честным - попадание части объекта в "квадрат" выделения, методы с boundingbox`ами годятся только для быстрого отсеивания сложных объектов которые точно не под мышью.

В случае, когда каждый примитив знает входит в него точка или нет, вряд ли это потребуется.
Хотя, для ускорения, вы правы: композитный объект может, на этапе формирования вычислять прямоугольник в который он входит. Проверка принадлежности точки объекту, в таком случае, сводится к проверке вхождения точки в этот прямоугольник. Если входит - уже производятся проверки для примитивов.

Кроме того, выделение происходит в 3д - т.к. если постоянно проекцировать объекты - будет очень тормозно.

Не знаю насчёт 3D. У меня сейчас никаких представлений на сей счёт не возникает.
Проекции, перекрытие, удалённость и прочее... Сложно.
Но, вообще, 3D - это всего лишь ещё одна плоскость. Т.е., всё возможно свести к X и Y.

пока планирую поведение с выделением только по границе (т.е. замкнутые объекты не выделяются по щелчку внутри, только на границе), из замкнутых объектов с заполнением у ченя пока только 3DFace, он недавно добавлен и еще толком не работает.

Если использовать схему выше, я думаю, что замкнутые объекты будут выделять себя сами, в каком месте не кликни. Главное использовать замкнутые примитивы (опять же, ориентируюсь на плоскость).

Насколько я понял в LCL класс TPanel не может обработать колесо мышки... как быть?

Будет ли работать так:
Код: Выделить всё
TMyPanel = class(TPanel)
  property OnMouseWheel;
  property OnMouseWheelDown;
  property OnMouseWheelUp;
end;
?

P.S.:
Нужно. но позже.

Позже я забыть могу. Да мне может и не до этого быть. :(
Выложу, на всякий. Если понадобится, будет под рукой.
glFont.h:
Код: Выделить всё
//---------------------------------------------------------------------------
#ifndef glFontH
#define glFontH
//---------------------------------------------------------------------------
#include <windows.h>
//#include <wstring.h>
#include <gl\gl.h>
#include <Graphics.hpp>
//---------------------------------------------------------------------------
#include "../defines.h"
//---------------------------------------------------------------------------
class glFont
{
private:
   bool FXCentered;
   bool FYCentered;
protected:
   GLuint FFontOffset;
   GLYPHMETRICSFLOAT FGmf[256];

   bool getXCentered() const {return FXCentered;};
   void setXCentered(bool value) {FXCentered = value;};
   bool getYCentered() const {return FYCentered;};
   void setYCentered(bool value) {FYCentered = value;};

public:
   glFont(HDC hDC, char* fontFace, GLfloat weight = 0,
     int type = WGL_FONT_POLYGONS);
   glFont(HDC hDC, TFont *font, GLfloat weight = 0,
     int type = WGL_FONT_POLYGONS);
   ~glFont();
   void __fastcall Put(const WideString& str) const;
//  void put(const char ch);
public:
   GLfloat __fastcall GetTextWidth(const WideString& str) const;
   GLfloat __fastcall GetTextHeight(const WideString& str) const;
   __property bool XCentered = {read = getXCentered, write = setXCentered};
   __property bool YCentered = {read = getYCentered, write = setYCentered};
};
//---------------------------------------------------------------------------
#endif

glFont.cpp:
Код: Выделить всё
//---------------------------------------------------------------------------
#pragma hdrstop
#include "glFont.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
glFont::glFont(HDC hDC, char* fontFace, GLfloat weight, int type) :
   FXCentered(true), FYCentered(true)
{
  HFONT hFont = CreateFontA(0/*height*/, 0/*width*/, 0/*aspect angle*/,
    0/*angle*/, 0, FALSE/*italic*/, FALSE/*underline*/, FALSE/*strike-out*/,
    RUSSIAN_CHARSET, OUT_TT_PRECIS/*render precision*/,
    CLIP_DEFAULT_PRECIS /*clip precision*/, ANTIALIASED_QUALITY/*quality*/,
    FF_DONTCARE|DEFAULT_PITCH, fontFace);
  if (hFont == NULL) return;

  FFontOffset = glGenLists(256);
  HGDIOBJ old = SelectObject(hDC, hFont);

  // wglUseFontBitmaps(hDC, 0, 256, fontOffset);
  wglUseFontOutlines(hDC, 0, 256, FFontOffset, 0.1, weight,
    type, FGmf);
  SelectObject(hDC, old);
  DeleteObject(hFont);

  return;
}
//---------------------------------------------------------------------------
glFont::glFont(HDC hDC, TFont* font, GLfloat weight, int type):
   FXCentered(true), FYCentered(true)
{
//  HFONT hFont = CreateFontA(0/*height*/, 0/*width*/, 0/*aspect angle*/,
//    0/*angle*/, 0, FALSE/*italic*/, FALSE/*underline*/, FALSE/*strike-out*/,
//    RUSSIAN_CHARSET, OUT_TT_PRECIS/*render precision*/, CLIP_DEFAULT_PRECIS/*clip precision*/,
//    ANTIALIASED_QUALITY/*quality*/, FF_DONTCARE|DEFAULT_PITCH, fontFace);
  if (font->Handle == NULL) return;

  FFontOffset = glGenLists(256);
  HGDIOBJ old = SelectObject(hDC, font->Handle);

  // wglUseFontBitmaps(hDC, 0, 256, fontOffset);
  wglUseFontOutlines(hDC, 0, 255, FFontOffset, 0.1, weight,
    type, FGmf);
  SelectObject(hDC, old);
//  DeleteObject(font->Handle);

  return;
}
//---------------------------------------------------------------------------
glFont::~glFont()
{
  glDeleteLists(FFontOffset, 256);
}
//---------------------------------------------------------------------------
GLfloat __fastcall glFont::GetTextWidth(const WideString& str) const
{
   GLfloat text_width = 0;
   for (register int i = 0; i < str.Length(); i++)
      text_width += FGmf[str[i]].gmfCellIncX;
   return(text_width);
}
//---------------------------------------------------------------------------
GLfloat __fastcall glFont::GetTextHeight(const WideString& str) const
{
   GLfloat text_height = 0;
   for (register int i = 0; i < str.Length(); i++)
      if (text_height < FGmf[str[i]].gmfBlackBoxY)
         text_height = FGmf[str[i]].gmfBlackBoxY;
   return(text_height);
}
//---------------------------------------------------------------------------
void __fastcall glFont::Put(const WideString &str) const
{
  //glRasterPos3f(x, y, z);
  if (FXCentered)
  {
    glTranslatef(-GetTextWidth(str) / 2, 0, 0);
  }

  if (FYCentered)
  {
    glTranslatef(0, -GetTextHeight(str) / 2, 0);
  }

  glPushAttrib(GL_LIST_BIT);
  glListBase(FFontOffset);
  glCallLists((GLsizei)str.Length(), GL_UNSIGNED_SHORT, _TEXT(str));
  glPopAttrib();
}
//---------------------------------------------------------------------------


Увы, пока только под window$. :(
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Вопросы по LCL

Сообщение zub » 23.06.2010 16:02:49

Тогда, я могу предположить, следует использовать не наследование, а включение объектов класса "линия" в новый класс "СУПЕРЛИНИЯ".

Если включать не примитивы, а элементарные объекты (содержащие только геометрические+визуальные свойства) - получится тоже самое что я говорю, но без выноса в отдельный слой. тоже вариант со своими минусами. Некоторые свойства примитивов зависят от графического контекста, например: видимость, детализация (кол-во отрезков для апроксимации окружностей), проекция (если ее приспичит использовать). Без выноса в отдельный слой - всё это хозяйство придется пересчитывать при отображении одних и техже примитивов в разных окнах (типа вид сверху+вид сбоку+перспектива).

Но, вообще, 3D - это всего лишь ещё одна плоскость. Т.е., всё возможно свести к X и Y.

как можно больше операций нужно делать в 3д. постоянно всё проецировать не вариант (я так уже пробовал делать - скорость никакая), если и проекцировать то уже отсеенный минимум объектов - например только находящиеся под мышкой.

Будет ли работать так:

Как оно может заработать если TPanel о них не в курсе? я чтото не понимаю?
У TPanel соответствующих пропертей нету, в TForm при кручении колеса над панелью ниче не приходит...

Выложу, на всякий. Если понадобится, будет под рукой.

ок. большое спасибо. wglUseFontOutlines наврятли подойдет, т.к. генерирует дисплейные списки - их содержимое на CPU не вытащить
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Вопросы по LCL

Сообщение А.Н. » 23.06.2010 19:56:12

Если включать не примитивы, а элементарные объекты (содержащие только геометрические+визуальные свойства) - получится тоже самое что я говорю, но без выноса в отдельный слой.

Ну получится, как-бы "слой" объектов, ведь так?

тоже вариант со своими минусами. Некоторые свойства примитивов зависят от графического контекста, например: видимость, детализация (кол-во отрезков для апроксимации окружностей), проекция (если ее приспичит использовать). Без выноса в отдельный слой - всё это хозяйство придется пересчитывать при отображении одних и техже примитивов в разных окнах (типа вид сверху+вид сбоку+перспектива).

Так, вроде, в любом случае придётся пересчитывать?

как можно больше операций нужно делать в 3д. постоянно всё проецировать не вариант (я так уже пробовал делать - скорость никакая), если и проекцировать то уже отсеенный минимум объектов - например только находящиеся под мышкой.

1. Отсеивать может базовый класс сложных объектов.
2. С 3D, наверное, всё очень похоже. Только сложнее математика. Я не представляю себе, потому и говорю о плоскости.

Как оно может заработать если TPanel о них не в курсе? я чтото не понимаю?
У TPanel соответствующих пропертей нету, в TForm при кручении колеса над панелью ниче не приходит..

А вы проверьте. ;) Если у TForm работают, то должны и у TPanel заработать. За работу со скроллом отвечает TControl.

wglUseFontOutlines наврятли подойдет, т.к. генерирует дисплейные списки - их содержимое на CPU не вытащить

В смысле?
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Вопросы по LCL

Сообщение zub » 23.06.2010 20:45:15

Ну получится, как-бы "слой" объектов, ведь так?

да
Так, вроде, в любом случае придётся пересчитывать?

пересчитывать только при изменении контекста. и хранить вместе с контекстом
1. Отсеивать может базовый класс сложных объектов.
2. С 3D, наверное, всё очень похоже. Только сложнее математика. Я не представляю себе, потому и говорю о плоскости.

Ну для этого базовый класс должен быть очень умный)). причем все объекты будут наследованы от "композитного" объекта - не очень хорошо. текущее положение дел - 20000 примитивов (в том числе "композитных") ~ 150MB памяти и предел комфортной работы на моем компе. Этого мало (а по памяти много. причем в программе пока не поддерживаются "типы линий" если каждая линия станет штрихпунктирнаой (будет состоять из ~100 отрезков-штрихов), будет вообще караул). Подход заключения одинаковых наборов примитивов в "блоки" и на месте их отображения вставлять только ссылку на этот "блок" не спасает. Изза отсутствия "элементарных" объектов на мете вставки для расчетов приходится копировать обычные объекты, тратя попусту память и ресурсы.
А вы проверьте. Если у TForm работают, то должны и у TPanel заработать. За работу со скроллом отвечает TControl.

действительно, в TControl есть. Странный подход - сначала сделать-потом спрятать. Хоть бы владельцу тогда посылались, просто пропадают
В смысле?

слабо представляю себе процесс форматирования текста состоящего из букв о которых ниче не известно (максимум что можно получить из дисплейного списка - ширину буквы. нарисовав его и посчитав смещение в модельной матрице). или перед рисованием обмерять буквы на обычном контексте? хотя наверно можно рисовать на текстуру и ее выводить вообще без wglUseFontOutlines
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Вопросы по LCL

Сообщение А.Н. » 23.06.2010 21:49:31

пересчитывать только при изменении контекста. и хранить вместе с контекстом

С контекстом OpenGL?

Ну для этого базовый класс должен быть очень умный)).

Никакой "умности".
Как я выше писал, базовый класс должен определять, при создании объекта, его крайние точки.
Т.е., хранить прямоугольник, за границы которого объект не выходит.
В случае трёхмерности - параллелепипед. С издержками на проекцию. Тут я не знаю.
Считается он просто - выбираются крайняя левая, крайняя правая, крайняя верхняя, крайняя нижняя,
крайняя передняя и крайняя задняя точки среди всех точек объектов, входящих в массив.
Пусть изо всех туда попадёт, ну, максимум 10 объектов (и то - напихать десять объектов - это круто).
Если есть вхождение точки в этот параллелепипед, начинает проверяться вхождение точки в примитивы, образующие объект. Если вхождение обнаружено, на этом проверка прерывается и объект считается выбранным. Проверку возможно начать либо спереди, либо сзади, либо "сбоку" %-|, в зависимости от угла поворота сцены.
Если каждый объект состоит из 10 примитивов (хотя, вроде, больше чем из 3-х, я у вас не заметил).
Тогда нужно проверить 100 примитивов - максимум.
Проверка вхождения точки в примитив крайне проста. К тому же, это чисто математическая операция.
Её, например, возможно на MMX какой-нибудь возложить, который поддерживается практически всем, на чём сможет работать ваша СAD. Проверка будет мгновенной.
Для выборки объектов, также возможно такой метод использовать.
Т.е., например, есть сцена, разбитая на кубы и хранящая координаты групп объектов, входящих в этот куб...
Причём, кубы также могут быть разбиты на более мелкие кубы. Ну и т.д...
http://www.gamedev.ru/articles/?id=30114

причем все объекты будут наследованы от "композитного" объекта - не очень хорошо.

Очень хорошо. Код базового класса содержится в памяти в единичном экземпляре (ну, должен, по-идее, не знаю, как во free pascal'е). К тому же, базовый класс весьма простой и всего лишь:
1.) Содержит массив/коллекцию/список объектов.
2.) Имеет методы для добавления/удаления/изменения примитивов.
3.) Имеет метод проверки вхождения, вначале через "квадраты", затем, используя методы примитивов.
4.) Содержит метод рисования (реализованный через вызов методов примитивов), метод выделения и т.п.
5.) Содержит дополнительный функционал.

причем в программе пока не поддерживаются "типы линий" если каждая линия станет штрихпунктирнаой (будет состоять из ~100 отрезков-штрихов), будет вообще караул).

А зачем делать пунктирную линию, используя отрезки? Почти везде поддерживаются стили линий (даже несмотря на то, что в 3.0 они deprecated). А там, где их нет, возможно реализовать это не через объекты, а через базовые возможности графической системы. Именно стиль.
Т.е., есть примитив "линия", который рисует не прямую линию, а линию отрезками, о чём известно только свойству Style и методу отрисовки (т.е., не LineTo(x, y), а for ... LineTo(xi, yi); MoveTo(xi + n, yi +m);).
Затратит лишь немногим больше проц. времени или немного больше памяти и времени GPU.

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

А иерархия блоков? Вообще, Кнут, кажется изрёк: "Нет ничего хуже преждевременной оптимизации."

слабо представляю себе процесс форматирования текста состоящего из букв о которых ниче не известно (максимум что можно получить из дисплейного списка - ширину буквы. нарисовав его и посчитав смещение в модельной матрице). или перед рисованием обмерять буквы на обычном контексте?

1. Для моих задач сильное форматирование и не нужно было.
Естественно, класс надо доделывать для этого. Но, думаю, что для window$ есть от чего отталкиваться.
2. Простую строку выводит метод Put(const WideString &s).
FGLFont->Put(str);.
glCallLists, сам устанавливает следующую позицию для вывода очередного символа.

Установка параметров шрифта производится при создании класса:
Код: Выделить всё
TFont* FFontOptions;
...
void __fastcall TBaseVisual::ClkglRecreateFonts()
{
   // Обязательно! Скорость здесь не важна, а если этого не сделать, то,
   // при многократной переустановке шрифтов, в окне настроек, на месте LCD,
   // будут появляться кракозябры.
   wglMakeCurrent(Fm_hDC, Fm_hRC);
   delete FGLFont;
   FGLFont = new glFont(Fm_hDC, FFontOptions, FFontThickness);
   //FLogoFont
}


В принципе, возможно иметь несколько таких объектов для разных типов шрифта или разных шрифтов.
Но, проблема в том, что они занимают много памяти и занимают пространство номеров дисплейных списков.
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Вопросы по LCL

Сообщение zub » 24.06.2010 00:06:16

С контекстом OpenGL?

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

Как я выше писал, базовый класс должен определять, при создании объекта, его крайние точки.
Т.е., хранить прямоугольник, за границы которого объект не выходит.
В случае трёхмерности - параллелепипед. С издержками на проекцию. Тут я не знаю.
Считается он просто - выбираются крайняя левая, крайняя правая, крайняя верхняя, крайняя нижняя,
крайняя передняя и крайняя задняя точки среди всех точек объектов, входящих в массив.
Пусть изо всех туда попадёт, ну, максимум 10 объектов (и то - напихать десять объектов - это круто).
Если есть вхождение точки в этот параллелепипед, начинает проверяться вхождение точки в примитивы, образующие объект.
Если вхождение обнаружено, на этом проверка прерывается и объект считается выбранным.
Проверку возможно начать либо спереди, либо сзади, либо "сбоку" %-|, в зависимости от угла поворота сцены.

Это сделано - строится AABB, для быстрого отсева ненужных примитивов. Не понял как предполагается вести проверку сбоку - примитивы в линейном списке

Каждый объект состоит из 10 примитивов (хотя, вроде, больше чем из 3-х, я у вас не заметил).
Тогда нужно проверить 100 примитивов - максимум
.
Число вложенных примитивов не ограничено (ну только пределами разумного), причем влогаться могут "композитные примитивы". также "композитный объект" применяет к вложенным свою матрицу трансформации (т.е. вложенные объекты находятся в системе координат владельца), может поменять некоторым вложенным примитивам цвет, толщину или тип линии.

Проверка вхождения точки в примитив крайне проста. К тому же, это чисто математическая операция.
Её, например, возможно на MMX какой-нибудь возложить, который поддерживает практически
всё на чём сможет работать ваша СAD. Проверка будет мгновенной.
Для выборки объектов, также возможно такой метод использовать.
Т.е., например, есть сцена, разбитая на кубы и хранящая координаты групп объектов, входящих в этот куб...
Причём, кубы также могут быть разбиты на более мелкие кубы. Ну и т.д...
http://www.gamedev.ru/articles/?id=30114

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

>>Очень хорошо. Код базового класса содержится в памяти в единичном экземпляре (ну, должен, по-идее, не знаю, как во free pascal'е). К тому
что хорошего? большинство примитивов никогда не будут иметь дочерних. Я еще понимаю в примитиве иметь список "элементарных" примитивов, но никак не обычных

Я чтото потерял нить спора:
Я планирую оторвать "графическую" реализацию примитивов и привязать ее к графическому контексту.
+независимость примитивов от графической системы (хотя будет зависимость от способа рисования себя, наверно хрен редьки не слаще)
+возможность мультирендера (принципиальная)
+более экономичные базовые классы
+более простое написание наследников
+более экономичный расход памяти
-усложнение кода самой программы (появление новых классов "элементарной" графики и системы их связи с примитивами)

То что предлагаете Вы сделано сейчас (с некоторыми оговорками)
+уже сделано и както работает))
-много забот у програмиста пишушего свои примитивы
-не возможность экономично сделать поддержку "типа линий" - а он мне нужен
-примитив привязан к графическому контексту, нет возможности быстро переключиться между окнами вывода - пока ненужно, но обидно :D

в первом случае единственный минус существеннен, во втором - единственный плюс тоже очень существеннен :D

А зачем делать пунктирную линию, используя отрезки? Почти везде поддерживаются стили линий (даже несмотря на то, что в 3.0 они deprecated). А там, где их нет, возможно реализовать это не через объекты, а через базовые возможности графической системы. Именно стиль.
Т.е., есть примитив "линия", который рисует не прямую линию, а линию отрезками, о чём известно только свойству Style и методу отрисовки (т.е., не LineTo(x, y), а for ... LineTo(xi, yi); MoveTo(xi + n, yi +m);).
Затратит лишь немногим больше проц. времени или немного больше памяти и времени GPU.

Существующие стили линии OLG - убогость, максимум их применения заштриховать выделенные объекты. В автокаде существует специальный язык для определения типов линий, т.е. пользователь может использовать свои типы. Тип линий может менять объекты до неузнаваемости, вплоть до полного искривления и появления текста вдоль линий. Например был квадрат - приминили к нему зигзагообразный тип - он стал отображаться непойми чем - "квадрозигом" :D. со всеми вытекающими - изменился его AABB, он выделяется за зигзаги и не выделяется в пустотах, где раньше была линия. вот я и хочу эти xi, yi выкинуть из примитива, а вместе с ними и всё остальное относящееся к графической системе.

А иерархия блоков? Вообще, Кнут, кажется изрёк: "Нет ничего хуже преждевременной оптимизации."

Преждевременная оптимизация это лесть в асм для ускорения цикла от 0 до 1000000, когда из этого ляма 999990 проходов можно безобидно выкинуть.
А с блоками нетак всё просто, обычный для GL подход (иметь определение блока (описание геометрии и цвета), на месте вставок этого определения - настраивать матрицы и вызывать процедуру рисования определения) не прокатывает. Вставка имеет свой набор параметров, в том числе цвет, толшина и тип линий. Если изменение вставкой цвета и толщиты для примитивов в определении еще можно побороть, то изменение геометрии типом линий - никак не поборешь. Приходится иметь на месте вставки измененную копию примитивов определения, это очень накладно.
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Вопросы по LCL

Сообщение А.Н. » 24.06.2010 14:56:32

Не понял как предполагается вести проверку сбоку - примитивы в линейном списке

"Сбоку" куба с примитивами. С той стороны, которая "впереди", в области видимости. Хм... Вспомнить бы ещё к чему я это говорил... %-|

"композитные примитивы". также "композитный объект" применяет к вложенным свою матрицу трансформации (т.е. вложенные объекты находятся в системе координат владельца), может поменять некоторым вложенным примитивам цвет, толщину или тип линии.
...
К тому
что хорошего? большинство примитивов никогда не будут иметь дочерних. Я еще понимаю в примитиве иметь список "элементарных" примитивов, но никак не обычных

Вот тут, кажется, расхождение в терминах. Под примитивом я имею ввиду элемент из которого строятся композитные объекты. Я предполагал, что композитные объекты могут строится только из примитивов, а не из других объектов. Хотя, может, из композитных объектов лучше делать, на перспективу, по крайней мере.

Я чтото потерял нить спора

Вроде, и спора-то не было. :)

-много забот у програмиста пишушего свои примитивы

Я-то говорю о том, что примитивы уже существуют, а добавлять пользователь может только композитные объекты.
Причём, "программирование" такого объекта сведётся к переопределению одного метода. И заключаться его построение будет в добавлении примитивов в массив и установке их свойств.
Т.е., всё "программирование", вообще возможно свести к тыканию мышкой.

Существующие стили линии OLG - убогость, максимум их применения заштриховать выделенные объекты. В автокаде существует специальный язык для определения типов линий, т.е. пользователь может использовать свои типы.

Хех. Дык, ваше дело. Только у меня есть подозрение, что придётся всю "архитектуру" переделывать, если вы хотите сделать описание объектов/линий внешним языком.

Тип линий может менять объекты до неузнаваемости, вплоть до полного искривления и появления текста вдоль линий. Например был квадрат - приминили к нему зигзагообразный тип - он стал отображаться непойми чем - "квадрозигом" :D. со всеми вытекающими - изменился его AABB, он выделяется за зигзаги и не выделяется в пустотах, где раньше была линия. вот я и хочу эти xi, yi выкинуть из примитива, а вместе с ними и всё остальное относящееся к графической системе.

Xi и Yi, всё-равно, не выкинуть. :) Поскольку, все эти "квадрозиги" :D вам придётся рисовать самостоятельно.
Я-то о более приземлённом. Есть линия. Это примитив.
У неё есть стиль: "прямая", "пунктир", "точка-тире-звездочка".
Первые два поддерживаются граф. подсистемой (пусть, OpenGL или другой).
И в методе рисования примитива просто устанавливается стиль линии.
Стиль линии "точка-тире-звездочка" не поддерживается графической подсистемой.
Поэтому, в методе рисования примитива, такая линия рисуется отдельным алгоритмом (с Xi, Yi :) ).
Если пользователю нужен новый стиль, то ему придётся определить новый класс и добавить, например, какое-нибудь свойство ExStyle, затем переопределить метод рисования.
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Вопросы по LCL

Сообщение zub » 24.06.2010 15:35:23

Хех. Дык, ваше дело. Только у меня есть подозрение, что придётся всю "архитектуру" переделывать, если вы хотите сделать описание объектов/линий внешним языком.
Xi и Yi, всё-равно, не выкинуть. Поскольку, все эти "квадрозиги" вам придётся рисовать самостоятельно.

Да, под переделку попадает много всего.
Вот еще пример: сейчас в программе асть 2 типа текстовых примитивов
Text - однострочный текст
МText - многострочный текст с элементарным форматированием
у них соответственно предок AbstractText, его методы берут содержимое текста (линию) и на основе SHX шрифта (тип линии) строят большой список координат (xi,yi). Этот список лежит вместе с объектом и переодически отсылается на ГПУ. Ну ведь само напрашивается этот список не хранить с объектом - он зависит от графической системы: single для OGL (можно в VBO загонять), int для GDI.

Добавлено спустя 8 часов 42 минуты 25 секунд:
Как в LCL обрабатывить клавиатуру? мне нужно ловить клавиши типа ESC, однако когда на форме есть TEdit все сообщения ему уходят и этот подлец нехочет фокус терять - сделав setfocus форме, она его снова отдает edit`у
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Вопросы по LCL

Сообщение А.Н. » 25.06.2010 00:49:43

Свойство формы: KeyPreview - уже не в моде? :)
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Вопросы по LCL

Сообщение zub » 25.06.2010 10:33:20

Свойство формы: KeyPreview - уже не в моде?

В нашей деревне про него не слышали)). Но это всеравно не совсем то, хотелось чтоб edit получал фокус только по шелчку на нем и терял его по enter`у (завершению ввода) или по щелчку мимо. Ну и когда фокус в едите, чтоб формы это никак не касалось

Добавлено спустя 3 часа 17 минут 32 секунды:
Еще:
Как можно уьрать рамку вокруг содержимого TPageControl`а? никак?
Я так понимаю TPageControl вообще какойто глюкавый, иногда (после изменения размеров сплитером) напрочь забывает что у него есть правая сторона рамки (перестает ее рисовать), иногда забывает обновить содержимое текущей вкладки пока туда не ткнешь мышкой.

Добавлено спустя 9 часов 3 минуты 39 секунд:
Ну и еще чуток дегтя:
Раньше загрузка тестового файла занимала 7 секунд. теперь 17...
Убрал индикацию на ProgressBar`е - стало 9, наверно если процедуру вывота текста в мемо поковырять, вернется снова на 7сек.
Мне за прогрессбар чтоли считать сдвинется у него шкала или нет и вызывать ProcessBar.position:=Сколько_надо? или просто попался неудачный SVN лазаря?
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Вопросы по LCL

Сообщение А.Н. » 26.06.2010 00:04:55

Но это всеравно не совсем то, хотелось чтоб edit получал фокус только по шелчку на нем и терял его по enter`у (завершению ввода) или по щелчку мимо. Ну и когда фокус в едите, чтоб формы это никак не касалось

А почему он его теряет по Enter'у? И по щелчку мимо, вроде бы, тоже фокус должен оставаться в edit.
Хотя не скажу точно. Возможно стоит попробовать поиграться с ActiveControl формы. Ведь, при клике на неё она должна устанавливать фокус в какой-то контрол. Может, при установке фокуса в edit, менять ActiveControl на него?

Как можно уьрать рамку вокруг содержимого TPageControl`а? никак?

Не могу на сей счёт сказать. Я использую манифест и рамки у меня нет. Но, если рамка есть в приложения написанных не на lazarus, убрать её возможно только через API (и то - не факт).
А зачем, вообще, это надо? Может, всё же лучше включить манифест?

Я так понимаю TPageControl вообще какойто глюкавый, иногда (после изменения размеров сплитером) напрочь забывает что у него есть правая сторона рамки (перестает ее рисовать),

В смысле, при "восстановлении" окна из maximize?

иногда забывает обновить содержимое текущей вкладки пока туда не ткнешь мышкой.

У меня тоже бывает.

Мне за прогрессбар чтоли считать сдвинется у него шкала или нет и вызывать ProcessBar.position:=Сколько_надо? или просто попался неудачный SVN лазаря?

Ну, вообще-то, ProcessBar.position. А разве по-другому возможно? Я не понимаю что не так.
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Вопросы по LCL

Сообщение zub » 26.06.2010 01:12:50

А почему он его теряет по Enter'у? И по щелчку мимо, вроде бы, тоже фокус должен оставаться в edit.
Хотя не скажу точно. Возможно стоит попробовать поиграться с ActiveControl формы. Ведь, при клике на неё она должна устанавливать фокус в какой-то контрол. Может, при установке фокуса в edit, менять ActiveControl на него?

про ActiveControl тоже не знал - попробую, спасибо. Нужно такое поведение - на форме постоянно есть 1 тедит, редактировать который можно только когда по нему щелкнешь мышью, при щелчке мимо он должен терять фокус для возможности организации буквенных шорткутов. Т.е. нажал "L" - она не ушла тедиту а попала на пример в обработчик формы, который запустит команду (процедуру) соответствующую этой букве.

Не могу на сей счёт сказать. Я использую манифест и рамки у меня нет. Но, если рамка есть в приложения написанных не на lazarus, убрать её возможно только через API (и то - не факт).
А зачем, вообще, это надо? Может, всё же лучше включить манифест?

ок, почитаю что такое манифест :oops:

В смысле, при "восстановлении" окна из maximize?

Если схватить скролбар и погонять туда-сюда интенсивно, то можно поймать положенья где содержимое TPageControl`а не отрисуется. в крайних положениях (1 панель вообще не видно, вторая соотметственно максимально вытянута) тоже не рисуется.

Ну, вообще-то, ProcessBar.position. А разве по-другому возможно? Я не понимаю что не так.

Смысл в том что при небольших изменениях position визуальное положение ProcessBar`а не меняется, а он всеравно при таких вызовах отрисовывается. иначе куда девается больше половины времени? У меня ProcessBar.max большой, ProcessBar.position меняется часто и не на много, почему не фильтруются незначимые визуально изменения? В моде фильтровать самому :D ?
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Вопросы по LCL

Сообщение А.Н. » 26.06.2010 10:51:05

Нужно такое поведение - на форме постоянно есть 1 тедит, редактировать который можно только когда по нему щелкнешь мышью, при щелчке мимо он должен терять фокус для возможности организации буквенных шорткутов. Т.е. нажал "L" - она не ушла тедиту а попала на пример в обработчик формы, который запустит команду (процедуру) соответствующую этой букве.

Хм... А точно стоит делать горячие клавиши зависимыми от элемента, который имеет фокус?

ок, почитаю что такое манифест :oops:

Проект->Параметры проекта->Приложение->Использовать manifest-файл для включения тем.
Стили под венду хп.

Если схватить скролбар и погонять туда-сюда интенсивно, то можно поймать положенья где содержимое TPageControl`а не отрисуется. в крайних положениях (1 панель вообще не видно, вторая соотметственно максимально вытянута) тоже не рисуется.

Ох, у меня бывает, что не прорисовываются даже контролы. Очень редко. Рамки едитов, например.
Стоит закрыть форму другим окном или сменить вкладку - всё становится нормально.
Я просто не обращаю внимания на такие вещи. На текущий момент, у меня не работает поиск - крайне медленно. Кое-что глючит.
Не отлажены основные процедуры. 35 пунктов (ещё и с подпунктами).
Если бы у меня было всё сделано и не было других дел, я бы стал думать о рамке вокруг страницы (если бы заметил).
Не знаю, может, конечно, для вас это важнее.

Смысл в том что при небольших изменениях position визуальное положение ProcessBar`а не меняется, а он всеравно при таких вызовах отрисовывается. иначе куда девается больше половины времени? У меня ProcessBar.max большой, ProcessBar.position меняется часто и не на много, почему не фильтруются незначимые визуально изменения? В моде фильтровать самому :D ?

Наверное, просто разработчики об этом не подумали. Как вариант, прибавлять, например 10 к position.
Чтобы была гарантированная отрисовка.
Ведь не обязательно же каждый % показывать?
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Вопросы по LCL

Сообщение zub » 26.06.2010 11:21:59

Проект->Параметры проекта->Приложение->Использовать manifest-файл для включения тем.
Стили под венду хп.

С манифестом почемуто перестает работать GDI отричовка, но ее один хрен убирать...

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

Ну я сейчас только переносом интерфейса занимаюсь, пытаюсь понять LCL. вот и обращаю вниманье на всё подряд. Мелочь, но должно работать, я ничего противозаконного вроде не делаю.

Ведь не обязательно же каждый % показывать?

Ок, приделаю сам, думал может какое свойство у ProcessBar`а есть отвечающее за это
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Вопросы по LCL

Сообщение А.Н. » 26.06.2010 12:35:58

С манифестом почемуто перестает работать GDI отричовка, но ее один хрен убирать...

Хм... Странно, что не работает. А отрисовка где?

Ну я сейчас только переносом интерфейса занимаюсь, пытаюсь понять LCL. вот и обращаю вниманье на всё подряд. Мелочь, но должно работать, я ничего противозаконного вроде не делаю.

Так-то так (хотя, если уж говорить, то и противозаконное за законное с успехом выдают, да и почти к любому "законному" возможно подкопаться и сделать противо- :-| ). Просто, я предполагаю, что рамка вокруг страницы - очень специфическая штука. И, скорее всего, везде так отображаться не будет. По-моему, не имеет смысла её убирать (а, учитывая то, что большинство не обратит внимания, вообще, не стоит с ней заморачиваться).

Ок, приделаю сам, думал может какое свойство у ProcessBar`а есть отвечающее за это

Есть некий Step... Но, учитывая что я не пользовался компонентом очень давно, я уже и не помню что к чему.
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Пред.След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 226

Рейтинг@Mail.ru