Discussion Board

Page 1 of 2 12 LastLast
Results 1 to 15 of 17
  1. #1
    Registered User popov_andrew_e's Avatar
    Join Date
    Oct 2010
    Posts
    20
    Может быть кто-нибудь сталкивался с этим.
    псевдокод:
    SetRect(iRect1);
    ...
    Draw();
    SetRect(iRect2);
    Draw();

    После вызова SetRect(iRect2) и ДО следующего вызова Draw на экране внутри области iRect2 выводится картинка, которая была
    нарисована предыдущим Draw(), но со смещением iRect2.iTl-iRect1.iTl и обрезанием по размеру iRect2.

    Другими словами, если, например iRect1 это весь экран, а iRect2 это некоторая его часть,
    то после вызова SetRect(iRect2) и ДО следующего вызова Draw symbian берет картинку всего экрана, вырезает из нее кусок TRect(TPoint(0,0),iRect2.Size()) и рисует его со смещением iRect2.iTl.
    Надеюсь объяснил понятно.
    Как избавится от такого кэширования ? Чтобы SetRect() ничего не менял на экране.
    Из-за этого в момент вызова SetRect() изображение мерцает.

  2. #2
    Nokia Developer Moderator truf's Avatar
    Join Date
    Jun 2007
    Location
    Moscow, Russia
    Posts
    1,355
    CCoeControl::SetRect()

    IMPORT_C void SetRect(const TRect &aRect);
    Description

    Sets the control's extent, specifying a rectangle.

    Note: calling this function results in a call to SizeChanged().
    Parameters
    const TRect &aRect

    The rectangle that defines the control's extent. The rectangle's origin is relative to the origin of its associated window.
    Т.е. Вызываете SetRect - меняется размер контрла. Потом он сдвигается. Все работает как и должно.

    А вы зачем ТАК используете SetRect? Чего вы хотите достичь в конечном итоге? Может вам CWindowGc::SetClippingRect(const TRect &) вместо этого нужен?

  3. #3
    Registered User popov_andrew_e's Avatar
    Join Date
    Oct 2010
    Posts
    20
    Quote Originally Posted by truf View Post
    Потом он сдвигается
    кем он сдвигается ?
    Draw() не вызывается, SizeChanged() у меня пустой.
    Мне кажется было бы логично при изменении размера контрола забыть все, что в нем было до этого нарисовано.

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

  4. #4
    Nokia Developer Moderator truf's Avatar
    Join Date
    Jun 2007
    Location
    Moscow, Russia
    Posts
    1,355
    Quote Originally Posted by popov_andrew_e View Post
    кем он сдвигается ?
    TRect имеет не только размер, но и позицию. Отсюда и движение до iRect2.iTl. Draw() - callback метод, он не может быть вызван системой пока вы не упадете в цикл event handler'а.

    Я правильно понял, что вы хотите нарисовать что то на весь экран при помощи контрола, а потом сжать его до нормальных размеров (скажем в кнопку)? При этом у вас должен оставаться нетронутым "фон". И вы это туда сюда разжимаете\сжимаете?

  5. #5
    Registered User popov_andrew_e's Avatar
    Join Date
    Oct 2010
    Posts
    20
    видимо мы друг друга не поняли
    то, что при вызове SetRect() сдвигается сам контрол это нормально и логично, собственно для этого и нужен SetRect(),
    но при этом в этот новый "сдвинутый" и "заресайзенный" контрол копируется содержимое контрола предыдущего размера и положения еще до вызова Draw(),
    получается symbyan считает, что в контроле с новым размером и положением должно быть нарисовано то же , что и в предыдущем.
    Draw() конечно обновить содержимое контрола, но делает он это не мгновенно, отсюда мерцание в момент изменения размера и положения контрола.

    путем установки SetRect(iRect1) при возникновении TPointerEvent::EDrag и SetRect(iRect2) после TPointerEvent::EButton1Up я реализовал перемешение маленького контрола по всему экрану.
    iRect1 это весь экран, iRect2 это размер самого контрола, фон прозрачный, размер области рисование контрола не меняется, меняется только его положение на экране.

  6. #6
    Registered User Ktulhu's Avatar
    Join Date
    Sep 2009
    Posts
    33
    Оно не копируется — оно просто не перерисовывается (имею в виду область, которая была занята контролом в предыдущий раз). Нужно реализовать отрисовку контейнера, в котором двигается контрол.

  7. #7
    Registered User popov_andrew_e's Avatar
    Join Date
    Oct 2010
    Posts
    20
    Quote Originally Posted by Ktulhu View Post
    Оно не копируется — оно просто не перерисовывается (имею в виду область, которая была занята контролом в предыдущий раз). Нужно реализовать отрисовку контейнера, в котором двигается контрол.
    оно именно копируется, еще до вызова моего Draw, говорю это с уверенностью т.к. в этой копии есть куски и моего контрола.
    Мой контрол сам себе главный контейнер, вокруг другие приложения.

    Наверное это вопрос выбора терминов : "копируется" - "не перерисовывается".
    Можно как-то выключить это копирование?
    Чтобы новый контрол до первого вызова Draw был абсолютно пустым.
    Last edited by popov_andrew_e; 2010-12-29 at 10:29.

  8. #8
    Registered User Ktulhu's Avatar
    Join Date
    Sep 2009
    Posts
    33
    Если в какой-то области остаются артефакты — это значит ошибка в реализации метода Draw контрола, который отвечает за данную область. Кеша никакого нет
    Last edited by Ktulhu; 2010-12-29 at 10:47.

  9. #9
    Registered User popov_andrew_e's Avatar
    Join Date
    Oct 2010
    Posts
    20
    Quote Originally Posted by Ktulhu View Post
    Кеша никакого нет
    поиграйтесь в эмуляторе с window-owning контролом, который меняет свой размер с бОльшего на меньший, будете удивлены

    Поковырялся в коде CCoeControl. Функция CCoeControl::SetRect() просто вызывает CCoeContrlol::SetExtent(), в последней стоит вызов RWindow::SetExtent(),
    из доки по RWindow::SetExtent():

    Sets the size and position of a window.
    This function may be called at any time after the window's Construct() function: the window's extent will change dynamically.
    If the window size is increased, any new area will be cleared to the background colour and a redraw event will be generated for it.

    Пока решил свою проблему заменой SetRect(iRect2) на SetExtent(iRect2.iTl,TSize(0,0)); SetRect(iRect2)

  10. #10
    Registered User Ktulhu's Avatar
    Join Date
    Sep 2009
    Posts
    33
    Было дело когда надо было нарисовать текстовку без ничто. В некоторых случаях оставались артефакты. Вроде и родительского окна нет, но нет и прозрачности которой хочется. Проблема была в CAppUi — его надо было наследовать от CAknAppUi а не CAknAppViewUi. Возможно при CAknAppViewUi создаётся родительское окошко (или группа окон), к которому цепляются прочие (сырцы ОС не смотрел, да и было давно). И у этого окошка конечно же нету функции отрисовки, которая корректно очистила бы экран в зоне его ответственности.

    Кеша, действительно нет. Буфера в которые идёт отрисовка — это нечто иное.

    PS. Я имею в виду когда контрол рисуется посреди экрана и на фоне видно меню с приложениями или главный экран. В общем нечто висит посреди экрана.

    PPS. Кроме того изменение размера может не привести к перерисовке контрола. Нужно не забывать вызывать Draw или DrawDeferred для контейнера
    Last edited by Ktulhu; 2010-12-31 at 11:42.

  11. #11
    Registered User popov_andrew_e's Avatar
    Join Date
    Oct 2010
    Posts
    20
    Quote Originally Posted by Ktulhu View Post
    PPS. Кроме того изменение размера может не привести к перерисовке контрола. Нужно не забывать вызывать Draw или DrawDeferred для контейнера
    Судя по этому посту, вы не поняли суть проблемы. Она в том, что в промежутке между вызовами SetRect() и Draw() window сервер успевает отобразить в контроле его предыдущую картинку без вызова Draw(), т.е закешированную (или забуферизированную - в ваших терминах)

  12. #12
    Registered User Ktulhu's Avatar
    Join Date
    Sep 2009
    Posts
    33
    То есть контрол ещё не отрисовался, но предыдущее изображение, которое было в контроле осталось? Оно в принципе так и должно работать.
    SetRect(anyRect);
    //старое изображение в контроле
    DrawNow();
    //новое изображение в конроле
    Возможно я действительно чего-то не понял В таком случае нужны дополнительные данные (кусок сырцов подойдёт)

  13. #13
    Registered User popov_andrew_e's Avatar
    Join Date
    Oct 2010
    Posts
    20
    тест-кейс готовить лениво
    нарисую в виде псевдокода для экрана с размером 360 на 640:
    Code:
    iRect1 = TRect(TPoint(0,0),TSize(360,640));
    iRect2 = TRect(TPoint(0,100),TSize(360,200));
    
    EnableWindowTransparency();
    Window().SetBackgroundColor(TRgb(0,0,0,0));
    SetRect(iRect2);
    gc.DrawRect(Rect());
    // на этом этапе на экране на фоне стартового рабочего стола изображен прямоугольник с абсолютными координатами (0,100)
    // приходит TPointerEvent::EDrag 
    SetRect(iRect1);
    // обрабатываем TPointerEvent и сдвигаем прямоугольник
    iRect2.Move(TPoint(0,50));
    // рисуем его
    gc.DrawRect(iRect2);
    // на этом этапе на экране на фоне стартового рабочего стола изображен прямоугольник с абсолютными координатами (0,150)
    // приходит TPointerEvent::EButton1Up, возвращаем контролу его рабочие размеры
    SetRect(iRect2);
    // а вот здесь проблема, на экране на фоне стартового рабочего стола изображен прямоугольник с абсолютными координатами (0,150+150), т.е.смещенный
    // рисуем
    gc.DrawRect(Rect());
    // здесь опять все нормально, изображен прямоугольник с абсолютными координатами (0,150)

  14. #14
    Registered User Ktulhu's Avatar
    Join Date
    Sep 2009
    Posts
    33
    Не понял. Идёт отрисовка внутри контрола или двигается окошко?

    Я похожее делал — посте №10. Просто подвешивается window owning контрол без родителей, с перекрытым Draw, устанавливается размер и потом просто передвигается по экрану с помощью SetPosition. Можно мимо него даже в рабочий стол ткнуть. Фишка в том, чтобы окошек сзади не было. Где-то был даже пример на эту тему. Если тыкать не надо, то этот контрол кладётся в контейнер, у которого тоже определён метод отрисовки (отрисовка прозрачным, вроде). Просто SetRect и затем SetPosition и оно ездит по экрану У меня оно ездило по таймеру, а не по событиям от тача

    ЗЫ

    Quote Originally Posted by popov_andrew_e View Post
    тест-кейс готовить лениво
    нарисую в виде псевдокода для экрана с размером 360 на 640:
    Code:
    iRect1 = TRect(TPoint(0,0),TSize(360,640));
    iRect2 = TRect(TPoint(0,100),TSize(360,200));
    
    EnableWindowTransparency();
    Window().SetBackgroundColor(TRgb(0,0,0,0));
    SetRect(iRect2);
    gc.DrawRect(Rect());
    // на этом этапе на экране на фоне стартового рабочего стола изображен прямоугольник с абсолютными координатами (0,100)
    // приходит TPointerEvent::EDrag 
    SetRect(iRect1);
    // обрабатываем TPointerEvent и сдвигаем прямоугольник
    iRect2.Move(TPoint(0,50)); // !!!! не понятно что вот это такое
    // рисуем его
    gc.DrawRect(iRect2); // !!!! это тоже не понятно
    // на этом этапе на экране на фоне стартового рабочего стола изображен прямоугольник с абсолютными координатами (0,150)
    // приходит TPointerEvent::EButton1Up, возвращаем контролу его рабочие размеры
    SetRect(iRect2);
    // а вот здесь проблема, на экране на фоне стартового рабочего стола изображен прямоугольник с абсолютными координатами (0,150+150), т.е.смещенный
    // рисуем
    gc.DrawRect(Rect());
    // здесь опять все нормально, изображен прямоугольник с абсолютными координатами (0,150)
    Может быть так
    Code:
    SetRect(iRect2);
    DrawNow();
    iRect2.Move(someWhere);
    SetRect(iRect2);
    DrawNow();
    Last edited by Ktulhu; 2010-12-31 at 15:06. Reason: детализация непоняток

  15. #15
    Registered User popov_andrew_e's Avatar
    Join Date
    Oct 2010
    Posts
    20
    И контрол двигается, и внутри него отрисовывается, изображение относительно границ контрола статично. Тыкать нужно и мимо него и в него, и перемещать его нужно именно пальцами

    в моем предыдущем посте вместо
    // а вот здесь проблема, на экране на фоне стартового рабочего стола изображен прямоугольник с абсолютными координатами (0,150+150), т.е.смещенный
    нужно читать
    // а вот здесь проблема, на экране на фоне стартового рабочего стола в прямоугольнике iRect2 изображен кусок рабочего стола TRect(TPoint(0,0),iRect2.Size()), тот, который был перед вызовом SetRect(iRect2)
    это про одно и то же, но второй вариант понятнее.

    если интересно и есть телефон на symbian^3 могу дать неподписанный sis

Page 1 of 2 12 LastLast

Similar Threads

  1. Положение экрана в Python приложении
    By alonan in forum Russian Developer Forum - Форум Российских разработчиков
    Replies: 2
    Last Post: 2010-03-07, 04:02
  2. Смена view при изменении ориентации экрана. uidesign
    By Kruil in forum Russian Developer Forum - Форум Российских разработчиков
    Replies: 4
    Last Post: 2010-02-25, 09:10
  3. Асинхронный вызов RConnection::Start
    By veon1 in forum Russian Developer Forum - Форум Российских разработчиков
    Replies: 19
    Last Post: 2009-09-02, 16:07
  4. Не работает авто-поворот экрана
    By metallugahell in forum Russian Developer Forum - Форум Российских разработчиков
    Replies: 1
    Last Post: 2009-07-07, 12:01
  5. Вызов функции в фоне
    By Mishatko in forum Russian Developer Forum - Форум Российских разработчиков
    Replies: 15
    Last Post: 2009-05-11, 11:54

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Nokia Developer aims to help you create apps and publish them so you can connect with users around the world.

京ICP备05048969号  © Copyright Nokia 2013 All rights reserved