Page MenuHomePhabricator

New Naviframe API
Closed, ResolvedPublic

Description

The goal of this task is to provide a new set of interface for Naviframe using T5350 infrastructure when it makes sense.

cedric raised the priority of this task from TODO to High.Jul 10 2017, 2:27 PM
jpeg assigned this task to Jaehyun_Cho.Dec 10 2017, 9:00 PM

It seems now that the original idea or having naviframe as window suffers from a couple of issues:

  • Required extra support from the compositor (we can't count on that except for E and only upstream)
  • More memory usage for surfaces (again, unless the compositor does its best to avoid leaving invisible surfaces in memory)
  • Lack of control over animations app-side (not even from app-specific theme)
  • No control over the stacking app-side (insert, remove, etc...)

A much simpler approach to naviframe, compared the original proposal, and compare to the legacy widget, could be implemented:

  • A simple container widget, with a single full-size slot for content. This slot doesn't need to be a swallow as the widget implementation could deal with sizing and positioning.
  • Standard background part, already handled by the widget class.
  • Overlay part for the index, also full size so that it may be placed wherever depending on theme (eg. dot-dot-dot in the bottom-center or n/N in the bottom-right corner, etc...)
  • No decoration, no title bar, no back button. Those should be handled by another kind of frame widget.

At least experimentally it would be interesting to see if we can build something like the above.
Note that this is similar to the pager widget, except that naviframe is a dynamic stack of "child" pages while pager is a static list of "sibling" pages.
No need for model here.

Required functions include:

  • push
  • pop
  • insert (above a given page, NULL means at the very back)
  • remove (from efl.container intf)

So, maybe call this a "Efl.Ui.Stack". Or something like page stack. (view relates to model apis)

Note:
This does not attempt to cover any of the requirements related to external applications (eg. an OAuth page, an app store window, etc...). The WL compositor widget could handle some of that but doesn't provide some of the security requirements out of the box (like making sure the app can not get the OAuth password as it's being typed in).

@Jaehyun_Cho
Would you share the class specification on this task ?

Here are brief specs of stack and navigation classes.

class Efl.Ui.Frame_Stack (Efl.Ui.Layout) //This probably can implement Efl.Stack or Efl.Ui.Stack interface

  • push (Eo *frame)
  • pop ()
  • insert
  • remove
  • top () //returns the top frame pointer

class Efl.Ui.Frame_Navigation (Efl.Ui.Layout, Efl.Content) //This probably can be changed to inherit Efl.Ui.Frame

  • back_btn is a part object
Jaehyun_Cho added a comment.EditedJan 15 2018, 9:14 PM

@woohyun @jpeg

Here, I need some opinions about the above class specs.

  1. class naming rule?
    • Based on elementary naming rule, stack should be Efl.Ui.Stack_Frame but it sounds not good.
  1. insert and remove with index or frame pointer?
    • insert(Eo *frame, int index) or insert(Eo *frame, Eo *base_frame)?
    • remove(int index) or remove(Eo *frame)?
  1. what happens if existing frame is pushed again?
    • promote the existing frame to the top or forbid pushing existing frame?
  1. title_bar can be a part object of Efl.Ui.Frame_Navigation?
jpeg added a comment.Jan 16 2018, 8:22 AM
  1. "Frame_Stack", no?
  2. both: insert_at, insert_after (optional), insert_before
  3. good question. probably promote. that's a corner case
  4. what is Frame_Navigation? a subclass/style of Frame? then, yes, i guess it could be? not sure :)

missing questions

  1. how to create a frame? and what if you push a non-frame object to a Frame_Stack?

@jpeg

  1. thanks for insert case. for remove case, it would be remove_at(Eo *frame, int index) remove(Eo *frame)
  1. frame is created by application side. e.g. Eo *frame = efl_add(EFL_UI_FRAME_NAVIGATION, frame_stack);

about non-frame object, I need to think more about it. (e.g. pushing popup case)

  1. Stacker, Frame_Stacker or Frame_Stack ? If this will only allow to insert Frame object, then Frame_Stack looks good.
  2. I also agree to promote it to the top.
  3. What is "title_bar" ? Text area for title ? or ... background area of title text ?
  4. I think many applications may want to pull their own Layout object. If we will only allow frame object, then , at least, we need to make a empty frame class for them.
jpeg added a comment.Feb 7 2018, 10:20 PM

Three components:

  • FrameStack, Frame, NavigationBar.
  • Client-side implementation since Tizen E won't support it well.
  • Use events to propagate things like "back button pressed" in this way: button -> bar -> frame -> stack. App should be able to listen to this publicly defined event (eg. "pop,requested").
  • Add "autopop" property, true by default, for each frame, so app can block frame pop on back button click (eg. in order to show a popup "do you want to save?").

@cedric @woohyun

This is the on-going classes for navigation.
Basically application developer creates Efl.Ui.Navigation_Frame class instance and push it into Efl.Ui.Frame_Stack class instance.

The brief eo files of Efl.Ui.Frame_Stack and Efl.Ui.Navigation_Frame are as follows.
@cedric @woohyun Please give me any feedback about this.

class Efl.Ui.Frame_Stack (Efl.Ui.Layout)
{

methods {
   push {
      [[Push a new object to the top of the frame stack (and show it).
      ]]

      params {
         @in frame: Efl.Canvas.Object;
      }
   }
   pop {
      [[Pop an object that is on top of the frame stack (and delete it).
      ]]

      return: Efl.Canvas.Object;
   }
   insert_before {
      [[Insert an object before the given frame in the frame stack.
      ]]

      params {
         @in frame: Efl.Canvas.Object;
         @in base_frame: Efl.Canvas.Object;
      }
   }
   insert_after {
      [[Insert an object after the given frame in the frame stack.
      ]]

      params {
         @in frame: Efl.Canvas.Object;
         @in base_frame: Efl.Canvas.Object;
      }
   }
   insert_at {
      [[Insert an object at the given place in the frame stack.
      ]]

      params {
         @in frame: Efl.Canvas.Object;
         @in index: int;
      }
   }
   remove {
      [[Remove the given object in the frame stack.
      ]]

      params {
         @in frame: Efl.Canvas.Object;
      }
   }
   remove_at {
      [[Remove an object at the given place in the frame stack.
      ]]

      params {
         @in index: int;
      }
   }
   index_get {
      [[Get the index of the given object in the frame stack.
        The index begins from bottom to top of the frame stack.
        The index of the bottom object is 0.
      ]]

      return: int;

      params {
         @in frame: Efl.Canvas.Object;
      }
   }
   frame_get {
      [[Get the object corresponding to the given index in the frame stack.
      ]]

      return: Efl.Canvas.Object;

      params {
         @in index: int;
      }
   }
   top {
      [[Get the top object in the frame stack.
      ]]

      return: Efl.Canvas.Object;
   }
}

}

class Efl.Ui.Navigation_Frame (Efl.Ui.Layout, Efl.Content)
{
}

@cedric @woohyun

For the title area of navigation frame, I have not decided how to design or implement it.
However, for now I have an idea as follows.

  1. Introduce Efl.Ui.Navigation_Bar class.
  2. navigation bar instance is automatically created inside navigation frame instance.

Here, there are many things to think about.

  1. is bar a property of navigation frame? or an efl_part of navigation frame?

2-1. if bar is a property, then is it ok to provide get/set to modify bar by application developer?
2-2. if bar is an efl_part, then how to modify bar's propery? and how to replace bar with other kind of bar? (e.g. replace Efl.Ui.Navigation_Bar class instance with Efl.Ui.Search_Bar or Efl.Ui.Tab_Bar class instance)

@cedric @woohyun
Please give me any feedback about this.

@cedric @woohyun

For the title area of navigation frame, I have not decided how to design or implement it.
However, for now I have an idea as follows.

  1. Introduce Efl.Ui.Navigation_Bar class.
  2. navigation bar instance is automatically created inside navigation frame instance.

    Here, there are many things to think about.
  3. is bar a property of navigation frame? or an efl_part of navigation frame? 2-1. if bar is a property, then is it ok to provide get/set to modify bar by application developer? 2-2. if bar is an efl_part, then how to modify bar's propery? and how to replace bar with other kind of bar? (e.g. replace Efl.Ui.Navigation_Bar class instance with Efl.Ui.Search_Bar or Efl.Ui.Tab_Bar class instance)

    @cedric @woohyun Please give me any feedback about this.

@cedric

Please give me some feed back on this.

@Jaehyun_Cho
If each Navigation_Bar needs different Navigation_Frame, then I think #2 is better.
If every Navigation_Bar needs only one Navigation_Frame with title area, then #1 looks better.

@cedric
Do you have any idea on this ?
If the both look ok, we can let @Jaehyun_Cho do something based on his decision.

Sorry, completely missed email comming from this task. I think we want to allow customisation of the navigation bar. So I guess that should drive the decision making here, and so I am not in favor of using efl_part here and more in favor of the property. Or did I miss something ?

OK, I will make "bar" as a property of frame for better customization :)

The Efl.Ui.Navigation_Frame eo is as follows to support title_bar as a property.

class Efl.Ui.Navigation_Frame (Efl.Ui.Layout, Efl.Content)
{

[[Navigation Frame widget                                                     
                                                                              
The Navigation_Frame widget provides a view form useful for navigation.          
]]                                                                            
methods {                                                                     
   @property title_bar {                                                      
      [[The title bar object.]]                                               
      set {                                                                   
      }                                                                       
      get {                                                                   
      }                                                                       
      values {                                                                
         value: Efl.Ui.Layout; [[The title bar object.]]                      
      }                                                                       
   }                                                                          
}                                                                             
implements {                                                                  
   Efl.Object.constructor;                                                    
   Efl.Content.content { set; get; }                                          
   Efl.Content.content_unset;                                                 
}

}

The Efl.Ui.Navigation_Bar eo is as follows to support back_button as its part object.

class Efl.Ui.Navigation_Bar (Efl.Ui.Layout, Efl.Content, Efl.Text, Efl.Ui.Translatable)
{

[[Navigation Bar widget                                                       
                                                                              
The Navigation_Bar widget provides a title bar form useful for navigation.       
]]                                                                            
parts {                                                                       
   back_button: Efl.Ui.Navigation_Bar.Part_Back_Button;                       
}                                                                             
implements {                                                                  
   Efl.Object.constructor;                                                    
   Efl.Content.content { set; get; }                                          
   Efl.Content.content_unset;                                                 
   Efl.Text.text { set; get; }                                                
   Efl.Ui.Translatable.translatable_text { set; get; }                        
   Efl.Part.part;                                                             
}

}

I am thinking of providing the following events in Efl.Ui.Frame_Stack.

events {                                                                      
   loaded;      [[Called when frame is loaded right before transition]]       
   unloaded;    [[Called when frame is unloaded right after being deactivated]]
   activated;   [[Called when frame is activated right after transition]]     
   deactivated; [[Called when frame is deactivated right after transition]]   
}
zmike edited projects, added Restricted Project; removed efl.Jun 11 2018, 6:54 AM
zmike edited projects, added efl: widgets; removed Restricted Project.Jun 11 2018, 8:15 AM
Jaehyun_Cho closed this task as Resolved.Jun 13 2018, 9:50 PM

This has been resolved.

Efl.Ui.Stack class has been introduced and it is used like elm_naviframe.

Efl.Ui.Navigation_Layout class instance is used as a content of the Efl.Ui.Stack class instance.

Efl.Ui.Navigation_Bar class instance is used as a title bar of the Efl.Ui.Navigation_Layout class instance.