Author Topic: Multiple Options in SelectionFilter  (Read 2866 times)

0 Members and 1 Guest are viewing this topic.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4076
Multiple Options in SelectionFilter
« on: December 13, 2010, 12:55:53 PM »
What I want to do is offer 2-8 options for a filter, and I know I've seen it, but I can't find the post showing it.  Something similiar to this
Code: [Select]
TypedValue[]  filter = { new TypedValue((int)DxfCode.Start , "INSERT"),new TypedValue (2,"TEP-INFO", "UES-INFO") };Of course it crashes as soon as I add the second string value
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4076
Re: Multiple Options in SelectionFilter
« Reply #1 on: December 13, 2010, 01:03:10 PM »
Found it here  Thanks Kerry
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Multiple Options in SelectionFilter
« Reply #2 on: December 13, 2010, 01:07:42 PM »
Was just about to post this link.  Another one from Kerry.

http://www.theswamp.org/index.php?topic=21930.msg264791#msg264791
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4076
Re: Multiple Options in SelectionFilter
« Reply #3 on: December 13, 2010, 02:22:18 PM »
Thanks Tim!  both are good examples of multiple choices.
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: Multiple Options in SelectionFilter
« Reply #4 on: December 13, 2010, 02:27:50 PM »
Hi,

You can have a look here too.
Speaking English as a French Frog

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Multiple Options in SelectionFilter
« Reply #5 on: December 13, 2010, 05:43:44 PM »
Hi,

You can have a look here too.

They asked for a username/password.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4076
Re: Multiple Options in SelectionFilter
« Reply #6 on: December 13, 2010, 06:36:23 PM »
Yea that looks like a new site that started after the fall of AUGI
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Multiple Options in SelectionFilter
« Reply #7 on: December 13, 2010, 06:48:41 PM »
Yea that looks like a new site that started after the fall of AUGI

before, actually. :)


Found it here  Thanks Kerry

You're most welcome.
I'm in parenthesis land mostly these days ... looking forward to using braces again soon. :)
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

kaefer

  • Guest
Re: Multiple Options in SelectionFilter
« Reply #8 on: December 15, 2010, 05:34:08 AM »
Brace yourself. I'd recommend the SelectionAdded event for filtering that's more than usually complicated.
Say we want to select Polylines with 100 < length <= 300 that are red and on layers FOO or BAR.

Exhibit #1: The straightforward C# approach.
Code: [Select]
    public class SelectionAddedCmd
    {
        bool myFilter(DBObject dbo)
        {
            var pl = dbo as Polyline;
            return
              pl != null &&
              pl.Length > 100.0 &&
              pl.Length <= 300.0 &&
              pl.ColorIndex == 1 &&
              pl.Layer == "FOO" ||
              pl.Layer == "BAR";
        }
        void selectionAdded(object sender, SelectionAddedEventArgs e)
        {
            var i = 0;
            foreach (SelectedObject so in e.AddedObjects)
            {
                if (!myFilter(so.ObjectId.GetObject(OpenMode.ForRead)))
                    e.Remove(i);
                i++;
            }
        }
        PromptSelectionResult selectWithFilter(Editor ed)
        {
            try
            {
                ed.SelectionAdded += new SelectionAddedEventHandler(selectionAdded);
                return ed.GetSelection();
            }
            finally
            {
                ed.SelectionAdded -= new SelectionAddedEventHandler(selectionAdded);
            }
        }
       
        [CommandMethod("SELFILC")]
        public void SelFilC()
        {
            var doc = acApp.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                var psr = selectWithFilter(ed);
                if (psr.Status == PromptStatus.OK && psr.Value.Count > 0)
                    ed.WriteMessage("\n{0} Objects selected", psr.Value.Count);
                else
                    ed.WriteMessage("\nNo Objects selected. ");
            }
        }
    }

Drawback: the predicate myFilter is hardcoded into the event handler. Compare this to

Exhibit #2: the F# proposal.
Code: [Select]
let (+=) e f = Observable.subscribe f e

let selectionIndexed =
    Seq.cast<SelectedObject> >> Seq.mapi (fun i so -> i, so.ObjectId)

let myFilter: DBObject->_ = function
    | :? Polyline as pl ->
        pl.Length > 100. &&
        pl.Length <= 300. &&
        pl.ColorIndex = 1 &&
        pl.Layer = "FOO" ||
        pl.Layer = "BAR"
    | _ -> false

let selectWithFilter (ed: Editor) f =
    use selectionAdded =
        ed.SelectionAdded +=
            fun e ->
                for (i, oid) in selectionIndexed e.AddedObjects do
                    if oid.GetObject OpenMode.ForRead |> f |> not then
                        e.Remove i
    ed.GetSelection()

[<CommandMethod "SELFILF">]
let selFilF() =
    let doc = acApp.DocumentManager.MdiActiveDocument
    let db = doc.Database
    let ed = doc.Editor
    use tr = db.TransactionManager.StartTransaction()

    let psr = selectWithFilter ed myFilter
    if psr.Status = PromptStatus.OK && psr.Value.Count > 0 then
        ed.WriteMessage("\n{0} Objects selected", psr.Value.Count)
    else
        ed.WriteMessage("\nNo Objects selected. ")

Now trying to replicate this in C# brings me into RX land, but it ain't very pretty.

Exhibit #3:
Code: [Select]
        ...
        void selectionAdded(SelectionAddedEventArgs e, Func<DBObject, bool> f)
        {
            var i = 0;
            foreach (SelectedObject so in e.AddedObjects)
            {
                if (!f(so.ObjectId.GetObject(OpenMode.ForRead)))
                    e.Remove(i);
                i++;   
            }
        }
        PromptSelectionResult selectWithFilter(Editor ed, Func<DBObject, bool> f)
        {
            IObservable<IEvent<SelectionAddedEventArgs>> selectionAddedAsObservable =
                    Observable.FromEvent<SelectionAddedEventHandler,SelectionAddedEventArgs>(
                        e => new SelectionAddedEventHandler(e),
                        h => ed.SelectionAdded += h,
                        h => ed.SelectionAdded -= h);
            using( var selectionAddedDisposable = selectionAddedAsObservable.Subscribe(a => selectionAdded(a.EventArgs, f))){
                return ed.GetSelection();
            }
        }
        ...
        var psr = selectWithFilter(ed, myFilter);
        ...

Any other suggestions to allow passing the predicate function to the event handler?

Greetings, Thorsten